truffle icon indicating copy to clipboard operation
truffle copied to clipboard

Custom error info not shown on method interaction using truffle develop

Open Aniket-Engg opened this issue 3 years ago • 7 comments

Issue

Truffle does not show solidity custom error information while calling a method using truffle develop

Steps to Reproduce

Call a method which fails by reverting with custom error.

Expected Behaviour

Custom error information with revert opcode

Actual Results

Shows plain revert as:

truffle(develop)> instance.list({value: 15})
Thrown:
{ Error: Returned error: VM Exception while processing transaction: revert

Environment

Operating System: MacOS Truffle v5.3.11 (core: 5.3.11) Solidity - 0.8.4 (solc-js) Node v11.15.0 Web3.js v1.3.6

Aniket-Engg avatar Jun 20 '21 10:06 Aniket-Engg

Yes, unfortunately this is not so easy. This is of course related to #3873. Unfortunately addressing this sort of thing is likely going to require some serious rewriting. We're planning to do that rewriting! But ti's not happening yet.

But then in addition we run into some more fundamental problems. Is instance.list a transaction or a call? I'm guessing the latter. Either way we have some problems:

  1. If it's a transaction, then we can't actually get the returned value to decode. This is already a problem currently with revert strings! Of course, if you're using Ganache in what is currently its default mode, where it errors on reverts and includes the revert string, that gets around this somewhat, but it won't get around it when interacting with a more standard Ethereum node. Also note that this method of getting around things relies on Ganache doing the decoding, and so won't work with custom errors, as Ganache can't really know about that sort of thing.
  2. If it's a call... well, that case is more handleable. (But, like I said, will require some serious rewriting before we can handle it.) We are hoping to get this case working eventually, but it's likely going to be a while. And that said, even in the cases we can handle, it should be noted that due to their nature one can never guarantee that decoding of a custom error will work.

So, this is something I would hope we can address eventually, but it's not likely to be soon.

haltman-at avatar Jun 22 '21 02:06 haltman-at

All that said, we did recently add support for custom errors in the Truffle Debugger, if you're looking for more information on what you can do in the meantime until we resolve this properly. :)

haltman-at avatar Jun 22 '21 02:06 haltman-at

Not 100% on topic, but I ran across this when trying to find a way to discriminate between custom errors introduced in Solidity 0.8.4. I ended up writing the following expectRevertError function with the help of this article. I hope it's helpful:

  const expectRevertError = async function(promise, expectedErrorSignature) {
    try {
      await promise;
    } catch (error) {
      const encoded = web3.eth.abi.encodeFunctionSignature(expectedErrorSignature);
      const returnValue = Object.entries(error.data).filter(it=>it.length>1).map(it=>it[1]).find(it=>it!=null && it.constructor.name==="Object" && "return" in it).return
      expect(returnValue).to.startWith(encoded);
      return;
    }
    expect.fail('Expected an exception but none was received');
  }

johnnylambada avatar Aug 06 '21 18:08 johnnylambada

hey @johnnylambada I understand that I'm asking a year later😁, but what is the error model that you get from the revert? I'm working with handling reverts made with customErrors now and getting just { message: string; stack: string } from revert. which is strange, information about the error lies as a string inside the message field, for example:

{
stack: 'Some javascript error description',
message: 'Error: Internal JSON-RPC error. { "code": 3, "message": "execution reverted", "data": "0x336cc9a5000000000000....00000000000182bbd86e62cfca"'
}

ko1ebayev avatar Oct 20 '22 09:10 ko1ebayev

Not 100% on topic, but I ran across this when trying to find a way to discriminate between custom errors introduced in Solidity 0.8.4. I ended up writing the following expectRevertError function with the help of this article. I hope it's helpful:

  const expectRevertError = async function(promise, expectedErrorSignature) {
    try {
      await promise;
    } catch (error) {
      const encoded = web3.eth.abi.encodeFunctionSignature(expectedErrorSignature);
      const returnValue = Object.entries(error.data).filter(it=>it.length>1).map(it=>it[1]).find(it=>it!=null && it.constructor.name==="Object" && "return" in it).return
      expect(returnValue).to.startWith(encoded);
      return;
    }
    expect.fail('Expected an exception but none was received');
  }

Thank you for this, works like a charm for me.

Usage is exactly like await truffleAssert.reverts. Second parameter should be you're error definition as a string. So for me things like "TokenDNE()".

johnnyshankman avatar Mar 25 '23 18:03 johnnyshankman

any updates on this issue?

DanielKillenberger avatar Aug 08 '23 11:08 DanielKillenberger

it's been two years guys

GorgeousPuree avatar Aug 12 '23 15:08 GorgeousPuree