Skip to content

Commit 43fa824

Browse files
joyeecheungtargos
authored andcommitted
process: refactor unhandled rejection handling
- Use constants instead of a dictionary and add comments about the behavior of each mode. - Use switch cases to handle the unhandled rejection modes. - Rename the run time value of the CLI option from `state` to `unhandledRejectionsMode`. - Return in the call site of `emitWarning` when `--unhandled-rejections=none` instead of inside the function. PR-URL: #28228 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent 32b0803 commit 43fa824

File tree

1 file changed

+57
-22
lines changed

1 file changed

+57
-22
lines changed

lib/internal/process/promises.js

+57-22
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,24 @@ const pendingUnhandledRejections = [];
2525
const asyncHandledRejections = [];
2626
let lastPromiseId = 0;
2727

28-
const states = {
29-
none: 0,
30-
warn: 1,
31-
strict: 2,
32-
default: 3
33-
};
34-
35-
let state;
28+
// --unhandled-rejection=none:
29+
// Emit 'unhandledRejection', but do not emit any warning.
30+
const kIgnoreUnhandledRejections = 0;
31+
// --unhandled-rejection=warn:
32+
// Emit 'unhandledRejection', then emit 'UnhandledPromiseRejectionWarning'.
33+
const kAlwaysWarnUnhandledRejections = 1;
34+
// --unhandled-rejection=strict:
35+
// Emit 'uncaughtException'. If it's not handled, print the error to stderr
36+
// and exit the process.
37+
// Otherwise, emit 'unhandledRejection'. If 'unhandledRejection' is not
38+
// handled, emit 'UnhandledPromiseRejectionWarning'.
39+
const kThrowUnhandledRejections = 2;
40+
// --unhandled-rejection is unset:
41+
// Emit 'unhandledRejection', if it's handled, emit
42+
// 'UnhandledPromiseRejectionWarning', then emit deprecation warning.
43+
const kDefaultUnhandledRejections = 3;
44+
45+
let unhandledRejectionsMode;
3646

3747
function setHasRejectionToWarn(value) {
3848
tickInfo[kHasRejectionToWarn] = value ? 1 : 0;
@@ -42,10 +52,23 @@ function hasRejectionToWarn() {
4252
return tickInfo[kHasRejectionToWarn] === 1;
4353
}
4454

55+
function getUnhandledRejectionsMode() {
56+
const { getOptionValue } = require('internal/options');
57+
switch (getOptionValue('--unhandled-rejections')) {
58+
case 'none':
59+
return kIgnoreUnhandledRejections;
60+
case 'warn':
61+
return kAlwaysWarnUnhandledRejections;
62+
case 'strict':
63+
return kThrowUnhandledRejections;
64+
default:
65+
return kDefaultUnhandledRejections;
66+
}
67+
}
68+
4569
function promiseRejectHandler(type, promise, reason) {
46-
if (state === undefined) {
47-
const { getOptionValue } = require('internal/options');
48-
state = states[getOptionValue('--unhandled-rejections') || 'default'];
70+
if (unhandledRejectionsMode === undefined) {
71+
unhandledRejectionsMode = getUnhandledRejectionsMode();
4972
}
5073
switch (type) {
5174
case kPromiseRejectWithNoHandler:
@@ -104,9 +127,6 @@ function handledRejection(promise) {
104127

105128
const unhandledRejectionErrName = 'UnhandledPromiseRejectionWarning';
106129
function emitWarning(uid, reason) {
107-
if (state === states.none) {
108-
return;
109-
}
110130
const warning = getError(
111131
unhandledRejectionErrName,
112132
'Unhandled promise rejection. This error originated either by ' +
@@ -129,7 +149,8 @@ function emitWarning(uid, reason) {
129149

130150
let deprecationWarned = false;
131151
function emitDeprecationWarning() {
132-
if (state === states.default && !deprecationWarned) {
152+
if (unhandledRejectionsMode === kDefaultUnhandledRejections &&
153+
!deprecationWarned) {
133154
deprecationWarned = true;
134155
process.emitWarning(
135156
'Unhandled promise rejections are deprecated. In the future, ' +
@@ -161,13 +182,27 @@ function processPromiseRejections() {
161182
}
162183
promiseInfo.warned = true;
163184
const { reason, uid } = promiseInfo;
164-
if (state === states.strict) {
165-
fatalException(reason);
166-
}
167-
if (!process.emit('unhandledRejection', reason, promise) ||
168-
// Always warn in case the user requested it.
169-
state === states.warn) {
170-
emitWarning(uid, reason);
185+
switch (unhandledRejectionsMode) {
186+
case kThrowUnhandledRejections: {
187+
fatalException(reason);
188+
const handled = process.emit('unhandledRejection', reason, promise);
189+
if (!handled) emitWarning(uid, reason);
190+
break;
191+
}
192+
case kIgnoreUnhandledRejections: {
193+
process.emit('unhandledRejection', reason, promise);
194+
break;
195+
}
196+
case kAlwaysWarnUnhandledRejections: {
197+
process.emit('unhandledRejection', reason, promise);
198+
emitWarning(uid, reason);
199+
break;
200+
}
201+
case kDefaultUnhandledRejections: {
202+
const handled = process.emit('unhandledRejection', reason, promise);
203+
if (!handled) emitWarning(uid, reason);
204+
break;
205+
}
171206
}
172207
maybeScheduledTicksOrMicrotasks = true;
173208
}

0 commit comments

Comments
 (0)