truffle
truffle copied to clipboard
Custom error info not shown on method interaction using truffle develop
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
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:
- 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.
- 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.
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. :)
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');
}
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"'
}
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()"
.
any updates on this issue?
it's been two years guys