Understanding Promise Rejections

In JavaScript, promises are used to handle asynchronous operations. A promise can either be fulfilled (resolved) or rejected. When using Ethers.js to interact with the Ethereum blockchain, many operations return promises. If an operation fails, it will reject the promise, and it's important to handle these rejections to avoid unhandled promise rejection errors.

Why Handle Promise Rejections?

Properly handling promise rejections is crucial for building robust applications. If a promise is rejected and not handled, it can lead to unexpected behavior, crashes, or a poor user experience. By catching these rejections, you can provide meaningful feedback to users and implement fallback logic.

How to Handle Promise Rejections

There are two primary ways to handle promise rejections in Ethers.js:

  • Using try...catch blocks with async/await.
  • Using the .catch() method on promises.

Sample Code for Handling Promise Rejections

Below is a complete HTML example demonstrating how to handle promise rejections when sending a transaction using Ethers.js:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ethers.js Promise Rejection Handling Example</title>
<script src="https://cdn.jsdelivr.net/npm/ethers@5.7.0/dist/ethers.umd.min.js"></script>
</head>
<body>
<h1>Send Ether with Promise Rejection Handling</h1>
<input type="text" id="recipientInput" placeholder="Enter recipient address" />
<input type="number" id="amountInput" placeholder="Enter amount in ETH" />
<input type="text" id="privateKeyInput" placeholder="Enter your private key" />
<button id="sendButton">Send Ether</button>
<pre id="transactionInfo"></pre>

<script>
async function sendEther() {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const recipient = document.getElementById('recipientInput').value;
const amount = document.getElementById('amountInput').value;
const privateKey = document.getElementById('privateKeyInput').value;

// Create a wallet instance
const wallet = new ethers.Wallet(privateKey, provider);

// Create a transaction object
const tx = {
to: recipient,
value: ethers.utils.parseEther(amount) // Convert amount to Wei
};

// Handling promise rejections using try...catch
try {
// Send the transaction
const transactionResponse = await wallet.sendTransaction(tx);
document.getElementById('transactionInfo').innerText = "Transaction Sent: " + transactionResponse.hash;

// Wait for confirmation
const receipt = await transactionResponse.wait();
document.getElementById('transactionInfo').innerText += "\\nTransaction Confirmed in Block: " + receipt.blockNumber;
} catch (error) {
// Handle the error
document.getElementById ('transactionInfo').innerText = "Error: " + error.message;
}
}

// Handling promise rejections using .catch()
function sendEtherWithCatch() {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const recipient = document.getElementById('recipientInput').value;
const amount = document.getElementById('amountInput').value;
const privateKey = document.getElementById('privateKeyInput').value;

// Create a wallet instance
const wallet = new ethers.Wallet(privateKey, provider);

// Create a transaction object
const tx = {
to: recipient,
value: ethers.utils.parseEther(amount) // Convert amount to Wei
};

// Send the transaction and handle promise rejections with .catch()
wallet.sendTransaction(tx)
.then(transactionResponse => {
document.getElementById('transactionInfo').innerText = "Transaction Sent: " + transactionResponse.hash;
return transactionResponse.wait();
})
.then(receipt => {
document.getElementById('transactionInfo').innerText += "\\nTransaction Confirmed in Block: " + receipt.blockNumber;
})
.catch(error => {
document.getElementById('transactionInfo').innerText = "Error: " + error.message;
});
}

document.getElementById('sendButton').onclick = sendEther;
</script>
</body>
</html>

Conclusion

Handling promise rejections in Ethers.js is essential for creating reliable and user-friendly applications. By using try...catch blocks or the .catch() method, you can effectively manage errors and provide users with clear feedback, ensuring a smoother experience when interacting with the Ethereum blockchain.