ethers.js
ethers.js copied to clipboard
Exposing stack trace in event of `Error: VM Exception while processing transaction:`
Hi,
When transactions revert, I'm almost always greeted with an error that loses all context around what line(s) of code triggered the error because the wait transaction method seemingly swallows all errors, even when surrounded by a try-catch block. Here's the output from a block of code surrounded by a try/catch block:
Error: VM Exception while processing transaction: reverted with reason string 'ProtocolControl: Only protocol admins can call this function.'
at <UnrecognizedContract>.<unknown> (0xb03fe543e5c90690a48b6a3ed444dc7661ba501d)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at runNextTicks (internal/process/task_queues.js:66:3)
at listOnTimeout (internal/timers.js:523:9)
at processTimers (internal/timers.js:497:7)
at EthModule._estimateGasAction (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:425:7)
at HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:117:18)
at EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)
Does anyone have any good ideas around preserving the stack trace of calls executed against ethers.js?
Thanks so much.
Here's an example code block:
try {
console.log("OK");
return await tx.wait();
} catch (err) {
const e = new Error();
console.error("Failed to send transaction, stacktrace", e.stack);
console.trace(err);
}
In this case, the OK is logged to the console, but the catch block is never reached. Its as if the wait method did not throw an error, even though there was a VM Exception during execution.
This continues to be my main pain-point with ethers. It can be difficult to debug scripts, tests, and frontend code due to losing the context surrounding the ethers call.
Would really love to fix this. Is there something fundamental about ethers' architecture that makes this necessary or makes it impossible for stack traces to be made more useful? I noticed, for example, that transactions seemed to be queued centrally, possibly explaining why the caller's stack trace gets lost
After a lot of time I've finally found a fix for the stack traces issue. The problem is the default stack trace size of node being 10. You can override it using NODE_OPTIONS=--stack-trace-limit=100. You can add this to your .profile or shell rc file as well: export NODE_OPTIONS=--stack-trace-limit=100.
Kind of related: there's also Error.stackTraceLimit which can be overriden individually.