2

I write a solidty code and also a custom error like this:

error TestObject__IndexNotFound();

function getProductChain(uint256 index) public view returns(SupplyChain memory){
    if (index > (counter - 1) || index < 0){
        revert TestObject__IndexNotFound();
    }
    SupplyChain memory spChain = supplyChain[index];
    return spChain;
}

But when i catch this error, the name of this error doesn't show:

 try{
     const transactionResponse = await contract.getProductChain(index);
     console.log(transactionResponse);
 }catch(error){
     console.log(error);
 }

Instead, it just writes 'revert' with no reason!. I can write require with string but I want to use error and revert. Last time when I used ethers and hardhat (node), the reverted error was shown in my console. But now it doesn't. I used ethers and ganache this time:

Error: missing revert data in call exception; Transaction reverted without a reason 
string....

2 Answers 2

1

I have answered a similar question here but I will do answer your question based on your example code too.

Here's how you can detect your error with ethers.js quite easily using ethers-decode-error.

Install ethers-decode-error in your project:

npm install ethers-decode-error --save

Next, the following code will help you get the name of the custom error in your solidity contract:

import { ErrorDecoder, DecodedError } from 'ethers-decode-error'

// You only have to do this once in your entire application
const errorDecoder = ErrorDecoder.create([contract.interface])

 try{
   const transactionResponse = await contract.getProductChain(index);
   console.log(transactionResponse);
 }catch(err){
  const { name } = await errorDecoder.decode(err)

  // Prints "TestObject__IndexNotFound" which is what you have named the error in your contract
  console.log('Custom error name:', name)
 }

If you want to match the different possible custom errors reverting from your contract with your own custom error messages, here's one way of doing it:

 try{
   const transactionResponse = await contract.getProductChain(index);
   console.log(transactionResponse);
 }catch(err){
  const decodedError = await errorDecoder.decode(err)
  const reason = customReasonMapper(decodedError)

  // Prints "This is a custom message for TestObject__IndexNotFound from my contract."
  console.log('Custom error message:', reason)
 }

const customReasonMapper = ({ name, reason }: DecodedError): string => {
  switch (name) {
    case 'TestObject__IndexNotFound':
      return `This is a custom message for ${name} from my contract.`

    // You can match other custom errors you may have in your contract here...
    // case 'MyOtherError': ...

    // Captures other error messages
    default:
      return reason ?? 'There was an error'
  }
}

You can find more examples for handling solidity custom errors here such as getting parameter values of custom errors, etc. :)

0

In ethers v6, you can use error.data that can be decoded from the contract to get the reverted error.

} catch (e) {
    if (e.data && contract) {
      const decodedError = contract.interface.parseError(e.data);
      console.log(`Transaction failed: ${decodedError?.name}`);
    } else {
      console.log(`Error in widthrawContract:`, e);
    }
  }

Detailled Example

Solidity

  modifier onlyOwner() {
        if (msg.sender != i_owner) revert FundMe__NotOwner();
        _;
    }

Browser code

export const widthrawContract = async () => {
  if (!isCryptoWalletAvailable()) return;
  let provider, signer, contract;
  try {
    console.log(`Widthrawing wallet...`);
    provider = new ethers.BrowserProvider(window.ethereum);
    signer = await provider.getSigner();
    contract = new ethers.Contract(FUND_ME_CONTRACT_ADDR, FUND_ME_ABI, signer);

    await contract.withdraw({});
  } catch (e) {
    if (e.data && contract) {
      const decodedError = contract.interface.parseError(e.data);
      console.log(`Transaction failed: ${decodedError?.name}`);
    } else {
      console.log(`Error in widthrawContract:`, e);
    }
  }
};

Error received from the browser:

Transaction failed: FundMe__NotOwner

In ethers V5, it's tiny different

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.