Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formatting revert error objects #871

Closed
zemse opened this issue Jun 6, 2020 · 8 comments
Closed

Formatting revert error objects #871

zemse opened this issue Jun 6, 2020 · 8 comments

Comments

@zemse
Copy link
Collaborator

zemse commented Jun 6, 2020

When a contract method reverts, it throws an error: "processing response error".

In the v5, the error.message contains lot of stuff including the actual rpc response from the node. While in v4, error.message contained only the error message string from the JSON RPC error.

try {
    await contract.methodThatReverts()
} catch (err) {
    console.log(err.message); // prints ethers error message containing the json rpc response as it is (along with error stacks from node if sent)
    console.log(err.error.message); // short and sweet error message
}

ethers v5 revert error object:

Error: processing response error (body={"id":247,"jsonrpc":"2.0","error":{"message":"VM Exception while processing transaction: revert invalid start block number","code":-32000,"data":{"stack":"RuntimeError: VM Exception while processing transaction: revert invalid start block number\n    at Function.RuntimeError.fromResults (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/ganache-core/lib/utils/runtimeerror.js:89:13)\n    at module.exports (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/ganache-core/lib/utils/gas/guestimation.js:142:32)","name":"RuntimeError"}}}, error={"code":-32000,"data":{"stack":"RuntimeError: VM Exception while processing transaction: revert invalid start block number\n    at Function.RuntimeError.fromResults (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/ganache-core/lib/utils/runtimeerror.js:89:13)\n    at module.exports (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/ganache-core/lib/utils/gas/guestimation.js:142:32)","name":"RuntimeError"}}, code=SERVER_ERROR, version=web/5.0.0-beta.141)
    at Logger.makeError (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/logger/lib/index.js:178:21)
    at Logger.throwError (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/logger/lib/index.js:187:20)
    at /Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/web/lib/index.js:181:32
    at step (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/web/lib/index.js:33:23)
    at Object.next (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/web/lib/index.js:14:53)
    at fulfilled (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/web/lib/index.js:5:58)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  reason: 'processing response error',
  code: 'SERVER_ERROR',
  body: {
    id: 247,
    jsonrpc: '2.0',
    error: {
      message: 'VM Exception while processing transaction: revert invalid start block number',
      code: -32000,
      data: [Object]
    }
  },
  error: Error: VM Exception while processing transaction: revert invalid start block number
      at getResult (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:70:21)
      at /Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/web/lib/index.js:175:46
      at step (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/web/lib/index.js:33:23)
      at Object.next (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/web/lib/index.js:14:53)
      at fulfilled (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/@ethersproject/web/lib/index.js:5:58)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:97:5) {
    code: -32000,
    data: {
      stack: 'RuntimeError: VM Exception while processing transaction: revert invalid start block number\n' +
        '    at Function.RuntimeError.fromResults (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/ganache-core/lib/utils/runtimeerror.js:89:13)\n' +
        '    at module.exports (/Users/sohamzemse/soham/kmpards/ESNCoreProjects/esn-contracts/node_modules/ganache-core/lib/utils/gas/guestimation.js:142:32)',
      name: 'RuntimeError'
    }
  }
}

ethers v4 revert error object (from a different project) looks like:

Error: VM Exception while processing transaction: revert insufficient balance
    at getResult (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/ethers/providers/json-rpc-provider.js:40:21)
    at exports.XMLHttpRequest.request.onreadystatechange (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/ethers/utils/web.js:111:30)
    at exports.XMLHttpRequest.dispatchEvent (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:25)
    at setState (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:14)
    at IncomingMessage.<anonymous> (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:447:13)
    at IncomingMessage.emit (events.js:333:22)
    at endReadableNT (_stream_readable.js:1201:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  code: -32000,
  data: {
    stack: 'RuntimeError: VM Exception while processing transaction: revert insufficient balance\n' +
      '    at Function.RuntimeError.fromResults (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/ganache-core/lib/utils/runtimeerror.js:89:13)\n' +
      '    at module.exports (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/ganache-core/lib/utils/gas/guestimation.js:142:32)',
    name: 'RuntimeError'
  },
  url: 'http://localhost:7566',
  body: '{"method":"eth_estimateGas","params":[{"from":"0x5C2807c2E86ECDdDA3537EdFAA7752Ac9bbF9fcD","to":"0x73f898B5C93115eE95ec02cE0811E4D07fC4aEF0","data":"0xa9059cbb000000000000000000000000ff9861f72d4989a94a20ec19f6005b15b61c1c6b000000000000000000000000000000004b3b4ca85a86c47a098a224000000000"}],"id":50,"jsonrpc":"2.0"}',
  responseText: '{"id":50,"jsonrpc":"2.0","error":{"message":"VM Exception while processing transaction: revert insufficient balance","code":-32000,"data":{"stack":"RuntimeError: VM Exception while processing transaction: revert insufficient balance\\n    at Function.RuntimeError.fromResults (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/ganache-core/lib/utils/runtimeerror.js:89:13)\\n    at module.exports (/Users/sohamzemse/soham/workspace/blockchain/ethereum/timeally/node_modules/ganache-core/lib/utils/gas/guestimation.js:142:32)","name":"RuntimeError"}}}'
}

Though I can access the revert message from err.error.message for now, I wanna confirm if reverts will be formatted in future, it might cause tests I'm writing to break.

@zemse zemse changed the title Revert error object formatting Formatting revert error objects Jun 6, 2020
@ricmoo
Copy link
Member

ricmoo commented Jun 6, 2020

That part should not change.

The revert reason at some point may be also available in the main error, but this requires a bit more effort, since it isn’t being fed back in a nice machine readable way and each backend seems to choose their own format. :(

@zemse
Copy link
Collaborator Author

zemse commented Jun 6, 2020

That part should not change.

I think it's fine if it did change during the beta/prerelease version. But that's great if the API doesn't change.

The revert reason at some point may be also available in the main error, but this requires a bit more effort

Did you mean extracting insufficient balance from Error: VM Exception while processing transaction: revert insufficient balance? Having the error message from RPC directly being set in the message property of error should also look fine. But if different eth backends do emit different error messages, it would definitely make sense to have a consistent error thrown through ethers.

each backend seems to choose their own format.

This can also be a call for standardizing the format across clients by proposing a simple addition in the ETH specification through which clients would stay consistent. It would make libraries to throw pretty errors and better errors in the UI too.

@ricmoo
Copy link
Member

ricmoo commented Jun 7, 2020

I agree, it'd be nice if there was a standard. Many parts of ethers tries to coalesce these errors already. For example, the various ways a node indicates "already seen" is captured and converted to a NONCE_EXPIRED error. The message from the server is still available, but many apps don'w need to worry about that. It is harder with app-generated errors.

I'm going to look at this right now. I might make the above throw a CALL_EXCEPTION error, instead of a SERVER_ERROR. Let me look into this for a day or two. :)

@ricmoo
Copy link
Member

ricmoo commented Jun 7, 2020

(once v5 is out of beta though, these things should almost certainly not change though; any change would have to wait until v6)

@ricmoo
Copy link
Member

ricmoo commented Jun 7, 2020

Actually, I tried this and got the CALL_EXCEPTION error, I'd expect. What backend are you using that returned a SERVER_ERROR instead?

@ricmoo
Copy link
Member

ricmoo commented Jun 7, 2020

Sorry for the spam.

Looks like you are using Ganache. If you use a normal backend, like Geth, you will probably get the correct error in response. I think there is a way to turn Ganache into "standards-compliant" mode... It would be nice if ethers could unpack this though and expose the error, but I don't know how feasible that is, since Ganache seems to change their output from time-to-time...

@zemse
Copy link
Collaborator Author

zemse commented Jun 7, 2020

If you use a normal backend, like Geth, you will probably get the correct error in response.

If it's giving a proper error on a standard client, that's really awesome! (I've not yet tried this with v5, will try later when deploying contracts on a test network).

I think there is a way to turn Ganache into "standards-compliant" mode...

I tried to look into docs (README) and issues of ganache-core and ganache-cli but couldn't find anything related. If you have any link or details handy right now, can you pls share?

It would be nice if ethers could unpack this though and expose the error, but I don't know how feasible that is, since Ganache seems to change their output from time-to-time...

If it's a trouble with Ganache, I don't think super important to also cover Ganache. As long as main clients like Geth and Parity/OpenEthereum are already covered, users would see a nice error in the UI. For the ganache part, developers can parse the error message if they need by themselves in their testcases depending on the test EVM or version they are using.

(once v5 is out of beta though, these things should almost certainly not change though; any change would have to wait until v6)

For now, I think ganache just giving an output like what current v4 is giving is enough instead of a processing response error, it would be nice for any smart contract developer upgrading to v5. Because currently, if a method throws in a mocha test, it shows 5-6 full lines of stuff in red. It can be replaced with just one red line: Error: VM Exception while processing transaction: revert insufficient balance. this might look a trivial request but it would be just a single line to read for a developer looking to understand the require statement that caused the test to fail.

zemse added a commit to KMPARDS/esn-contracts that referenced this issue Jun 10, 2020
@ricmoo
Copy link
Member

ricmoo commented Aug 24, 2021

I think this issue may be stale, so I'm closing it. If not, please feel free to re-open or start a new issue/discussion.

Thanks! :)

@ricmoo ricmoo closed this as completed Aug 24, 2021
maxymkotko added a commit to maxymkotko/EraSwap-Contract that referenced this issue Dec 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants