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

[Question] Error format depending on the EVM backend ? #42

Open
challet opened this issue Jan 2, 2023 · 6 comments
Open

[Question] Error format depending on the EVM backend ? #42

challet opened this issue Jan 2, 2023 · 6 comments

Comments

@challet
Copy link
Contributor

challet commented Jan 2, 2023

Hello, while using Ganache as a development backend, some errors are not handled as expected.
For instance with the following one (the context is a call to ethers estimateGas method which makes a dry run of the transaction and so can throw similar errors as the actual transaction):

{
	"code": -32603,
	"data": {
		"code": -32000,
		"data": {
			"hash": null,
			"message": "revert",
			"programCounter": 1420,
			"reason": "[revert message]",
			"result": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c34303920436f6e666c6963740000000000000000000000000000000000000000"
		},
		"message": "VM Exception while processing transaction: revert [revert message]",
		"name": "RuntimeError",
		"stack": "RuntimeError: VM Exception while processing transaction: revert [revert message]\n    at exactimate ([path]/node_modules/ganache/dist/node/1.js:2:182333)"
	},
	"message": "Internal JSON-RPC error."
}

It is parsed as { errorCode: 'UNKNOWN_ERROR', context: '-32603' } while imho it should return the EXECUTION_REVERTED one :

EXECUTION_REVERTED: "EXECUTION_REVERTED",

The text message looks really specific to Ganache and I'm wondering whether the whole error structure is also specific to it. How could it be then handled by the error parser ?

@enzoferey
Copy link
Owner

Hey @challet ! Indeed Ganache is probably changing the format a bit, but maybe there is a way to make it compatible. Are you using https://github.com/trufflesuite/ganache#as-an-ethersjs-provider ? Could you share some code around how you are populating and executing transactions ?

@challet
Copy link
Contributor Author

challet commented Jan 2, 2023

Are you using https://github.com/trufflesuite/ganache#as-an-ethersjs-provider ?

Actually no, because I'm using ganache CLI and then connecting my dapp through @wagmi/core publicProvider : it wraps an Ethers StaticJsonRpcProvider and doesn't involve any error handling.

This is the code I'm using (several parts pasted together, hopefully without omission):

import { configureChains, createClient, getContract, getProvider, prepareWriteContract, writeContract, InjectedConnector } from '@wagmi/core'
import { publicProvider } from '@wagmi/core/providers/public'
import { localhost } from '@wagmi/core/chains'
import { getParsedEthersError } from '@enzoferey/ethers-error-parser'
import type { Contract } from 'ethers'
import type { EthersError } from '@enzoferey/ethers-error-parser'

// configure wagmi
const { provider, chains } = configureChains(
  [localhost],
  [publicProvider()]
)
// it creates a singleton that will be used internally by other wagmi functions
createClient({
  autoConnect: true,
  connectors: [new InjectedConnector({ chains })],
  provider
})
// […]
const contract: Contract = await getContract({
  address, abi, signerOrProvider: getProvider()
})
try {
  const config = await prepareWriteContract({ // this function calls `estimateGas`
    address: contract.address,
    abi: contract.interface.fragments,
    functionName: 'myFunction' // method of the contract that is reverting the transaction
  })
  trx = await writeContract(config)
} catch (e) {
  console.log(getParsedEthersError(e as EthersError))
}

I'm trying to dig into ethers to see where it can differ from the expected format (maybe in the providers, maybe in the backend).

@challet
Copy link
Contributor Author

challet commented Jan 3, 2023

Tracing it back into Metamask, that is the raw error received from the backend being re-thrown without modification by ethers or a provider.
Or maybe it's always (Ganache and other EVM engines) like that when the error is thrown from an estimateGas operation ?

@challet
Copy link
Contributor Author

challet commented Jan 3, 2023

In fact, I see two scenarios here for the same error but with a different format (with or without Ganache, even though there might still be an other layer of difference in using it).

call to estimateGas (for later use its result as an argument of populateTransaction)

That's the one I'm reporting. The backend error is not caught (or re-thrown without change) by estimateGas and then bubbles up to the stack. See here

call to populateTransaction without prior estimate

It is caught by populateTransaction (which calls estimateGas) here and rethrown as UNPREDICTABLE_GAS_LIMIT. That's the one already handled here

@enzoferey
Copy link
Owner

Thanks for all the details @challet ! 🙏🏻

Maybe indeed we do not support the estimateGas call indeed, I would need to test it out. I'm a bit busy these days, but I will get to it as soon as possible and let you know 👍🏻

@challet
Copy link
Contributor Author

challet commented Jan 4, 2023

Imho, the problem is on the ethers side where it should throw the same error for both cases. There is no hurry and please consider it a discussion in progress as I'm a bit confused in how the various providers and signers work, especially if they all behave the same. I opened a discussion on the ethers repo about it : ethers-io/ethers.js#3618

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