How to get the revert reason on a smart contract function Ethers JS

In this tutorial, we are going to learn how to get the reason why a transaction reverted when calling a smart contract function using Ethers JS and JavaScript.

In this tutorial, we are going to learn how to get the reason why a transaction reverted when calling a smart contract function using Ethers JS and JavaScript.

Getting the revert reason is not very straightforward but it's still possible.

For that, you need to simulate sending the transaction that calls the smart contract function and catch the errors:

const ethers = require("ethers")

const provider = await ethers.providers.Web3Provider(YOUR_PROVIDER_HERE)

// create a Contract instance
const myNft = new ethers.Contract(address, ABI, provider)

// call a function that creates a transaction
myNft.mint(1, { value: ethers.utils.parseEther("0.1") })
.then((transaction) => {
    console.log("The transaction was successful")
    // you can wait for more confirmations if you want or get the receipt here
})
.catch(async (error) => {
    // The error message MIGHT contain the revert reason but you have to split the string to get it which might not work if the error message changes.
    
    // simulate transaction to get an error object using callStatic
    try {
        await myNft.callStatic.mint(1, { value: ethers.utils.parseEther("0.1") });
    } catch (error) {
        // if the smart contract reverted the transaction, the reason property contains the revert reason
        if (error.code === "CALL_EXCEPTION") {
            console.log("The revert reason is:", error.reason);
        }
        
        // if there is not enough gas
        if (error.code === "INSUFFICIENT_FUNDS") {
            console.log("Not enough gas to make the transaction")
        }
    }
})

You might think that you can get the error in the catch block of the mint function. But at that point, the error looks like this:

Error: VM Exception while processing transaction: reverted with reason string 'You are not allowed to mint'
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at runNextTicks (node:internal/process/task_queues:65:3)
    at listOnTimeout (node:internal/timers:526:9)
    at processTimers (node:internal/timers:500:7)
    at HardhatNode._mineBlockWithPendingTxs 

So you could split the string and just get what's in between the quotes 'You are not allowed to ming' but if someday the format of the error changes, your code is broken.

Also, you can't handle the other errors that might happen when you do that.

So to handle errors properly, in the catch block, you can simulate the transaction which doesn't cost any gas and has no effect on the blockchain, it just runs locally.

By doing that, you'll get an error object which looks like this:

{
  reason: 'You are not allowed to mint',
  code: 'CALL_EXCEPTION',
  method: 'mint(uint256)',
  data: '0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001b596f7520617265206e6f7420616c6c6f77656420746f206d696e740000000000',
  errorArgs: [ 'You are not allowed to mint' ],
  errorName: 'Error',
  errorSignature: 'Error(string)',
  address: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
  args: [ 1 ],
  transaction: {
    data: '0xa0712d680000000000000000000000000000000000000000000000000000000000000001',
    to: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
    from: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
    gasLimit: BigNumber { value: "29021464" },
    value: BigNumber { value: "100000000000000000" }
  }
}

Based on the error code, you can know why the transaction failed and if the error code is "CALL_EXCEPTION" then the reason property indicates the reason why it reverted.

The reason property will contain the exact message that the smart contract sends when it reverts the transaction.

Another example: if the error code is "INSUFFICIENT_FUNDS" it means the user doesn't have enough funds to pay for the gas fees.

You can see all the error codes and what they mean here:

Logging
Documentation for ethers, a complete, tiny and simple Ethereum library.

And that's it 🎉

Thank you for reading this article