Async/await destroys stack traces in NodeSaturday, September 29, 2018
And it's a terrible mess, and nobody should use it until this is fixed. Yeah I said it. The internet is already full of "5 reasons async/await blows Promises away" and "How to escape callback hell with async/await", only thing they all fail to mention is that is that it will lead to errors that are missing crucial stack trace information.
The following example code produces the correct stack trace:
(node:21652) UnhandledPromiseRejectionWarning: Error: Problem: hello at f4 (/home/myuser/projects/asyncpoc/index.js:5:11) at f3 (/home/myuser/projects/asyncpoc/index.js:3:17) at f2 (/home/myuser/projects/asyncpoc/index.js:2:17) at f1 (/home/myuser/projects/asyncpoc/index.js:1:79) at Object.<anonymous> (/home/myuser/projects/asyncpoc/index.js:8:1) at Module._compile (internal/modules/cjs/loader.js:689:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10) at Module.load (internal/modules/cjs/loader.js:599:32) at tryModuleLoad (internal/modules/cjs/loader.js:538:12) at Function.Module._load (internal/modules/cjs/loader.js:530:3)
The first 4 lines is the valuable information we need. Now let's change
f4 to be async, and have an
await statement, and re-run it:
(node:22122) UnhandledPromiseRejectionWarning: Error: Problem: hello at f4 (/home/myuser/projects/asyncpoc/index.js:6:11) at process._tickCallback (internal/process/next_tick.js:68:7) at Function.Module.runMain (internal/modules/cjs/loader.js:745:11) at startup (internal/bootstrap/node.js:266:19) at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)
The first line is the only somewhat relevant information, which points to the line where the
throw happened, it's missing crucial calls from before it, and everything else is completely useless. It took me an hour of debugging to narrow down the code what is causing this, and it's the first
await call. I found a github issue opened on Node from 2017 March 15, and it's closed because it has to do with V8, and there is nothing to be done in Node. This is absolutely fucking outragous, it's a serious bug, and it is already part of the language since Node 8, but nobody from the developers think it's serious enough, that this "feature" should maybe stay hidden behind a feature flag, or show some warnings that you should not use this if you care about debugging. The only indication of this behavior is in a closed github ticket. You call some 3rd party library that internally uses async/await, and you are now subject to this.
I'd much rather have the promise chaining syntax in my code, than errors that don't show where they are coming from.