Description
Is your feature request related to a problem? Please describe.
Unwieldy or incorrect behavior related to stack traces from unhandled promise rejections, depending on command-line options used.
Follow-up to #32312 (comment) and #17871.
Describe the solution you'd like
Add a new runtime flag:
process.unhandledRejections = 'strict';
This should behave the same way as setting --unhandled-rejections=strict
when launching Node.js.
Relevant documentation for already existing feature: https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
This new flag should also be documented near here: https://nodejs.org/api/process.html#process_process_throwdeprecation
After landing #32312, this situation has gotten better. However the stack trace from such an error is still overly long and unwieldy (lots of extraneous information):
Stack trace with `process.throwDeprecation = true;` after #32312
$ echo 'process.throwDeprecation = true; async function x() { throw new Error( "aaaa" ) }; x()' > test.js; ~/code/node/out/Release/node test.js; rm test.js(node:7885) UnhandledPromiseRejectionWarning: Error: aaaa
at x (/home/james/test.js:1:61)
at Object.<anonymous> (/home/james/test.js:1:84)
at Module._compile (internal/modules/cjs/loader.js:1147:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
at Module.load (internal/modules/cjs/loader.js:996:32)
at Function.Module._load (internal/modules/cjs/loader.js:896:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
(node:7885) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
internal/process/warning.js:135
throw warning;
^
DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
at emitDeprecationWarning (internal/process/promises.js:161:11)
at processPromiseRejections (internal/process/promises.js:213:13)
at processTicksAndRejections (internal/process/task_queues.js:98:32) {
name: 'DeprecationWarning',
code: 'DEP0018'
}
With --unhandled-rejections=strict
the output is somewhat cleaner:
Stack trace with `--unhandled-rejections=strict`
$ echo 'async function x() { throw new Error( "aaaa" ) }; x()' > test.js; ~/code/node/out/Release/node --unhandled-rejections=strict test.js; rm test.js
/home/james/test.js:1
async function x() { throw new Error( "aaaa" ) }; x()
^
Error: aaaa
at x (/home/james/test.js:1:28)
at Object.<anonymous> (/home/james/test.js:1:51)
at Module._compile (internal/modules/cjs/loader.js:1147:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
at Module.load (internal/modules/cjs/loader.js:996:32)
at Function.Module._load (internal/modules/cjs/loader.js:896:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
Why a further change is needed
Currently there is not an easy and foolproof way to get guaranteed error exits from unhandled rejections, with clean stack traces. The best current solution is to change how all Node.js processes are launched and add --unhandled-rejections=strict
to their command line. In a complex system, there are multiple ways that Node.js processes can be launched, so this is difficult to achieve fully.
This solution of adding a new runtime flag should allow us to just add a single line to our code instead, which should guarantee the desired behavior for all scripts that contain this line.