summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/internal/process/promises.js79
1 files changed, 57 insertions, 22 deletions
diff --git a/lib/internal/process/promises.js b/lib/internal/process/promises.js
index 324541551e..031997fc1b 100644
--- a/lib/internal/process/promises.js
+++ b/lib/internal/process/promises.js
@@ -25,14 +25,24 @@ const pendingUnhandledRejections = [];
const asyncHandledRejections = [];
let lastPromiseId = 0;
-const states = {
- none: 0,
- warn: 1,
- strict: 2,
- default: 3
-};
-
-let state;
+// --unhandled-rejection=none:
+// Emit 'unhandledRejection', but do not emit any warning.
+const kIgnoreUnhandledRejections = 0;
+// --unhandled-rejection=warn:
+// Emit 'unhandledRejection', then emit 'UnhandledPromiseRejectionWarning'.
+const kAlwaysWarnUnhandledRejections = 1;
+// --unhandled-rejection=strict:
+// Emit 'uncaughtException'. If it's not handled, print the error to stderr
+// and exit the process.
+// Otherwise, emit 'unhandledRejection'. If 'unhandledRejection' is not
+// handled, emit 'UnhandledPromiseRejectionWarning'.
+const kThrowUnhandledRejections = 2;
+// --unhandled-rejection is unset:
+// Emit 'unhandledRejection', if it's handled, emit
+// 'UnhandledPromiseRejectionWarning', then emit deprecation warning.
+const kDefaultUnhandledRejections = 3;
+
+let unhandledRejectionsMode;
function setHasRejectionToWarn(value) {
tickInfo[kHasRejectionToWarn] = value ? 1 : 0;
@@ -42,10 +52,23 @@ function hasRejectionToWarn() {
return tickInfo[kHasRejectionToWarn] === 1;
}
+function getUnhandledRejectionsMode() {
+ const { getOptionValue } = require('internal/options');
+ switch (getOptionValue('--unhandled-rejections')) {
+ case 'none':
+ return kIgnoreUnhandledRejections;
+ case 'warn':
+ return kAlwaysWarnUnhandledRejections;
+ case 'strict':
+ return kThrowUnhandledRejections;
+ default:
+ return kDefaultUnhandledRejections;
+ }
+}
+
function promiseRejectHandler(type, promise, reason) {
- if (state === undefined) {
- const { getOptionValue } = require('internal/options');
- state = states[getOptionValue('--unhandled-rejections') || 'default'];
+ if (unhandledRejectionsMode === undefined) {
+ unhandledRejectionsMode = getUnhandledRejectionsMode();
}
switch (type) {
case kPromiseRejectWithNoHandler:
@@ -104,9 +127,6 @@ function handledRejection(promise) {
const unhandledRejectionErrName = 'UnhandledPromiseRejectionWarning';
function emitWarning(uid, reason) {
- if (state === states.none) {
- return;
- }
const warning = getError(
unhandledRejectionErrName,
'Unhandled promise rejection. This error originated either by ' +
@@ -129,7 +149,8 @@ function emitWarning(uid, reason) {
let deprecationWarned = false;
function emitDeprecationWarning() {
- if (state === states.default && !deprecationWarned) {
+ if (unhandledRejectionsMode === kDefaultUnhandledRejections &&
+ !deprecationWarned) {
deprecationWarned = true;
process.emitWarning(
'Unhandled promise rejections are deprecated. In the future, ' +
@@ -161,13 +182,27 @@ function processPromiseRejections() {
}
promiseInfo.warned = true;
const { reason, uid } = promiseInfo;
- if (state === states.strict) {
- fatalException(reason);
- }
- if (!process.emit('unhandledRejection', reason, promise) ||
- // Always warn in case the user requested it.
- state === states.warn) {
- emitWarning(uid, reason);
+ switch (unhandledRejectionsMode) {
+ case kThrowUnhandledRejections: {
+ fatalException(reason);
+ const handled = process.emit('unhandledRejection', reason, promise);
+ if (!handled) emitWarning(uid, reason);
+ break;
+ }
+ case kIgnoreUnhandledRejections: {
+ process.emit('unhandledRejection', reason, promise);
+ break;
+ }
+ case kAlwaysWarnUnhandledRejections: {
+ process.emit('unhandledRejection', reason, promise);
+ emitWarning(uid, reason);
+ break;
+ }
+ case kDefaultUnhandledRejections: {
+ const handled = process.emit('unhandledRejection', reason, promise);
+ if (!handled) emitWarning(uid, reason);
+ break;
+ }
}
maybeScheduledTicksOrMicrotasks = true;
}