ethers.js icon indicating copy to clipboard operation
ethers.js copied to clipboard

Exposing stack trace in event of `Error: VM Exception while processing transaction:`

Open atbe opened this issue 3 years ago • 2 comments

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.

atbe avatar Dec 25 '21 19:12 atbe

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.

atbe avatar Dec 25 '21 19:12 atbe

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

landakram avatar Jun 15 '22 20:06 landakram

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.

shark0der avatar Feb 17 '23 10:02 shark0der

Kind of related: there's also Error.stackTraceLimit which can be overriden individually.

shark0der avatar Feb 17 '23 10:02 shark0der