ethers.js: Better (more informative) error message when wrong network

Obviously it should be my responsibility as a developer to ensure smooth UI.

Libraries should help.

Rinkeby: all working fine.

Mainnet selected in Metamask:

ethers.umd.js:5701 Uncaught (in promise) Error: call revert exception (method="balanceOf(address)", errorSignature=null, errorArgs=[null], reason=null, code=CALL_EXCEPTION, version=abi/5.0.7)
    at Logger.makeError (ethers.umd.js:5701)
    at Logger.throwError (ethers.umd.js:5710)
    at Interface.decodeFunctionResult (ethers.umd.js:10638)
    at Contract.<anonymous> (ethers.umd.js:11737)
    at step (ethers.umd.js:11464)
    at Object.next (ethers.umd.js:11445)
    at fulfilled (ethers.umd.js:11436)

Took me some effort of debugging to figure it out.

Something that would help:

Ensure that the address exists, correct network yada yada

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (8 by maintainers)

Most upvoted comments

Given that extra rpc call adds costs due to the “pay per call” model of most providers, it is reasonable to not do this. When a dev actually gets the error during development, having a message similar to call reverted or contract is not deployed to this address/network would hint developer to look in to both of these possible cases. This would definitely reduce frustration (in my last company many of colleagues were stuck at exact this error multiple times)

@zemse there is actually a extcodehash too, which would be even cheaper, since then it only needs to lookup in the root state trie; code size still has to fetch the code to derive its size.

That said, it is only available after a certain hardfork and this would also mean storing another address in the code that may not exist on all networks; I can deploy it to rinkeby, mainnet, ropsten, etc. but then what of test networks people create locally or networks I’m unaware of or cannot acquire ether for.

I think it is something just linking to docs that says basically: “is your contract deployed? Sometimes build tools do not update artifact files correctly, please make sure the address is correct and for debugging try getCode to make sure your contract exists and the bytecode is present”.

Which reminds me of another common cause of this I will need to mention. Often people add a new method to a contract but the artifact fails to update the address (or the developers hard coded value isn’t updated, or have hardcoded the address multiple places and failed to update one), so they complain of call exceptions when the version of the contract is newer than the one they are actually calling (which is missing the new method)… I should include instructions on how to decompile bytecode and search for their method.

Basically, with Turing complete things there are a (countably) infinite number of thing that can go wrong. The best I can do is provide documentation on trying to diagnose them. 😃

Why would energy, bandwidth and storage go to zero?! That’s definitely not how blockchains work. :p

If you are making an HTTP request, the bandwidth is absolutely not zero. Fetching the code requires looking up the codehash in the state trie and then further fetching the code from the indexed code database.

It is your responsibility as a developer to make sure you are talking to the correct address for the correct contract; a random error in the error console is of very little use to the end user, so it is only useful during development and debugging, and (possibly) CS. But it is bad practice to rely on an error to check you are on the correct network; it’s much cheaper (and substantially safer) to check that yourself when selecting the contract address.

If you use INFURA, you will see you pay for each request, for Alchemy you pay will various number of compute units depending on the operation. If you run your own infrastructure, at scale you would quickly discover why these services charge for these operations. Definitely not zero. 😃

That’s what I’m saying, I plan to add a link in the error message to the docs that will explain the various causes for a given error. There is no need to double the cost to the app owner for every error though.

In V4, it used to error contract not deployed. I agree that was super helpful. But since V5 it throws CALL_EXCEPTION. @ricmoo Would this be a bug or was this intentional? (until now I assumed that this was intentional maybe due to the expensive call to getCode).