3

I have already searched the web and on this site there is this question but with no solution.

I'm using ethers.js on browser with MetaMask.

I need to know the real reason for the failure, not just whether it fails or not, as shown here on polygonscan: enter image description here

Thanks

1
  • It's a common problem situation. You can use Remix to debug this. Usually you can obtain more information by increasing the gas limit. Oct 11, 2021 at 11:51

3 Answers 3

4

It can be done!

enter image description here

See here how to do it: https://gist.github.com/gluk64/fdea559472d957f1138ed93bcbc6f78a

const a = await provider.getTransaction('0xdc6506137b443a6ad6734b0047a6d00d31748110589b379d72461bc57e510e94');
try {
  let code = await provider.call(a, a.blockNumber)
} catch (err) {
  const code = err.data.replace('Reverted ','');
  console.log({err});
  let reason = ethers.utils.toUtf8String('0x' + code.substr(138));
  console.log('revert reason:', reason);
}

I just checked with a real contract released on Polygon Mainnet: the require message is obtainable.

8
  • You get the "out of gas" message. But can you get a custom message? That way you could know what went wrong with your smart contract.
    – Sky
    Oct 20, 2021 at 8:33
  • @Sky yes, also the custom message set in require appears. Oct 20, 2021 at 10:07
  • Could you then make it so that it returns "Print this message if condition1 != contition2" instead of "out of gas"? Because I haven't seen that, anywhere.
    – Sky
    Oct 20, 2021 at 10:18
  • @Sky did you tried this in solidity code? require(condition, "my message"); Oct 20, 2021 at 10:39
  • Yeah, written a number of functions. And I only get a reply in ganache-testNet, but never on the main net.
    – Sky
    Oct 20, 2021 at 10:40
2

Updated answer in 2024:

Here's an example of using ethers-decode-error to get the actual error message quite easily:

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

const errorDecoder = ErrorDecoder.create()

const WETH = new ethers.Contract('0xC02aa...756Cc2', abi, provider)
try {
  const tx = await WETH.transfer('0x0', amount)
  await tx.wait()
} catch (err) {
  const { reason } = await errorDecoder.decode(err)
  // Prints "ERC20: transfer to the zero address"
  console.log('Revert reason:', reason)
}

It's almost identical to the example in the original answer except that there is now an ErrorDecoder and supports ethers v6. You can refer to the docs here for more examples

The original answer below was using ethers v5, which you can still refer to if you are using it.

Original Answer:

You can check out ethers-decode-error v1 for getting the real error of a failed transaction. This utility also allows you to retrieve custom errors if needed.

In the example below, you are able to get the exact actual error message and do whatever you want with it quite easily:

import { decodeError } from 'ethers-decode-error'

const WETH = new ethers.Contract('0xC02aa...756Cc2', abi, provider)
try {
  const tx = await WETH.transfer('0x0', amount)
  await tx.wait()
} catch (err) {
  const { error } = decodeError(err)
  // Prints the real error message "ERC20: transfer to the zero address"
  console.log('Revert reason:', error)
}

You can refer to the v1 docs here for more examples

1

This is a common problem. You often get "out of gas" or some other default error, instead of a more detailed answer.

The reason for this is simple. If the transaction fails (for whatever reason), it's reverted and nothing is written into the blockchain.

If I wanted for the smart contract to return a "console log", I would first need to catch the error after it failed. But that is impossible as the transaction is getting reverted immediately after the error appears. Thus your "console log" will never get activated, and thus no detailed error report.

You might wanna try using solidity require() function

require(condition1 == condition2, "Print this message if condition1 != contition2");

However, this never worked for me on the main net. Instead I used local testNet ganache etc.

3
  • What do you mean with "this will not work on the main net"? The require woks also on mainnet, so the message is also dispatched. Isn't true? Oct 12, 2021 at 8:07
  • I was never able to get back the message on the main net. Only on Ganache (development tool). If somebody knows why that is, I would love to get an answer.
    – Sky
    Oct 12, 2021 at 8:30
  • see my answer ;-) Oct 15, 2021 at 8:11

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.