process: improve unhandled rejection message
PR-URL: https://github.com/nodejs/node/pull/17158 Refs: https://github.com/nodejs/node/pull/16768 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
c6b7052bb7
commit
13db29b2f7
@ -60,11 +60,25 @@ function setupPromises(scheduleMicrotasks) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function emitWarning(uid, reason) {
|
function emitWarning(uid, reason) {
|
||||||
|
try {
|
||||||
|
if (reason instanceof Error) {
|
||||||
|
process.emitWarning(reason.stack, 'UnhandledPromiseRejectionWarning');
|
||||||
|
} else {
|
||||||
|
process.emitWarning(
|
||||||
|
safeToString(reason), 'UnhandledPromiseRejectionWarning'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
const warning = new Error(
|
const warning = new Error(
|
||||||
`Unhandled promise rejection (rejection id: ${uid}): ` +
|
'Unhandled promise rejection. This error originated either by ' +
|
||||||
safeToString(reason));
|
'throwing inside of an async function without a catch block, ' +
|
||||||
|
'or by rejecting a promise which was not handled with .catch(). ' +
|
||||||
|
`(rejection id: ${uid})`
|
||||||
|
);
|
||||||
warning.name = 'UnhandledPromiseRejectionWarning';
|
warning.name = 'UnhandledPromiseRejectionWarning';
|
||||||
warning.id = uid;
|
|
||||||
try {
|
try {
|
||||||
if (reason instanceof Error) {
|
if (reason instanceof Error) {
|
||||||
warning.stack = reason.stack;
|
warning.stack = reason.stack;
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
(node:*) UnhandledPromiseRejectionWarning: Error: This was rejected
|
||||||
|
at * (*test*message*unhandled_promise_trace_warnings.js:*)
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
|
at *
|
||||||
(node:*) Error: This was rejected
|
(node:*) Error: This was rejected
|
||||||
at * (*test*message*unhandled_promise_trace_warnings.js:*)
|
at * (*test*message*unhandled_promise_trace_warnings.js:*)
|
||||||
at *
|
at *
|
||||||
|
@ -6,8 +6,11 @@ const expectedDeprecationWarning = 'Unhandled promise rejections are ' +
|
|||||||
'rejections that are not handled will ' +
|
'rejections that are not handled will ' +
|
||||||
'terminate the Node.js process with a ' +
|
'terminate the Node.js process with a ' +
|
||||||
'non-zero exit code.';
|
'non-zero exit code.';
|
||||||
const expectedPromiseWarning = 'Unhandled promise rejection (rejection id: ' +
|
const expectedPromiseWarning = 'Unhandled promise rejection. ' +
|
||||||
'1): [object Object]';
|
'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(). (rejection id: 1)';
|
||||||
|
|
||||||
function throwErr() {
|
function throwErr() {
|
||||||
throw new Error('Error from proxy');
|
throw new Error('Error from proxy');
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
|
|
||||||
|
const expectedValueWarning = 'Symbol()';
|
||||||
const expectedDeprecationWarning = 'Unhandled promise rejections are ' +
|
const expectedDeprecationWarning = 'Unhandled promise rejections are ' +
|
||||||
'deprecated. In the future, promise ' +
|
'deprecated. In the future, promise ' +
|
||||||
'rejections that are not handled will ' +
|
'rejections that are not handled will ' +
|
||||||
'terminate the Node.js process with a ' +
|
'terminate the Node.js process with a ' +
|
||||||
'non-zero exit code.';
|
'non-zero exit code.';
|
||||||
const expectedPromiseWarning = 'Unhandled promise rejection (rejection id: ' +
|
const expectedPromiseWarning = 'Unhandled promise rejection. ' +
|
||||||
'1): Symbol()';
|
'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(). (rejection id: 1)';
|
||||||
|
|
||||||
common.expectWarning({
|
common.expectWarning({
|
||||||
DeprecationWarning: expectedDeprecationWarning,
|
DeprecationWarning: expectedDeprecationWarning,
|
||||||
UnhandledPromiseRejectionWarning: expectedPromiseWarning,
|
UnhandledPromiseRejectionWarning: [
|
||||||
|
expectedPromiseWarning,
|
||||||
|
expectedValueWarning
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// ensure this doesn't crash
|
// ensure this doesn't crash
|
||||||
|
@ -12,18 +12,43 @@ let b = 0;
|
|||||||
process.on('warning', common.mustCall((warning) => {
|
process.on('warning', common.mustCall((warning) => {
|
||||||
switch (b++) {
|
switch (b++) {
|
||||||
case 0:
|
case 0:
|
||||||
assert.strictEqual(warning.name, 'UnhandledPromiseRejectionWarning');
|
// String rejection error displayed
|
||||||
assert(/Unhandled promise rejection/.test(warning.message));
|
assert.strictEqual(warning.message, 'This was rejected');
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
assert.strictEqual(warning.name, 'DeprecationWarning');
|
// Warning about rejection not being handled (will be next tick)
|
||||||
|
assert.strictEqual(warning.name, 'UnhandledPromiseRejectionWarning');
|
||||||
|
assert(
|
||||||
|
/Unhandled promise rejection/.test(warning.message),
|
||||||
|
'Expected warning message to contain "Unhandled promise rejection" ' +
|
||||||
|
'but did not. Had "' + warning.message + '" instead.'
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
// One time deprecation warning, first unhandled rejection
|
||||||
|
assert.strictEqual(warning.name, 'DeprecationWarning');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// Number rejection error displayed. Note it's been stringified
|
||||||
|
assert.strictEqual(warning.message, '42');
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
// Unhandled rejection warning (won't be handled next tick)
|
||||||
|
assert.strictEqual(warning.name, 'UnhandledPromiseRejectionWarning');
|
||||||
|
assert(
|
||||||
|
/Unhandled promise rejection/.test(warning.message),
|
||||||
|
'Expected warning message to contain "Unhandled promise rejection" ' +
|
||||||
|
'but did not. Had "' + warning.message + '" instead.'
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
// Rejection handled asynchronously.
|
||||||
assert.strictEqual(warning.name, 'PromiseRejectionHandledWarning');
|
assert.strictEqual(warning.name, 'PromiseRejectionHandledWarning');
|
||||||
assert(/Promise rejection was handled asynchronously/
|
assert(/Promise rejection was handled asynchronously/
|
||||||
.test(warning.message));
|
.test(warning.message));
|
||||||
}
|
}
|
||||||
}, 3));
|
}, 6));
|
||||||
|
|
||||||
const p = Promise.reject('This was rejected');
|
const p = Promise.reject('This was rejected'); // Reject with a string
|
||||||
setImmediate(common.mustCall(() => p.catch(() => {})));
|
setImmediate(common.mustCall(() => p.catch(() => { })));
|
||||||
|
Promise.reject(42); // Reject with a number
|
||||||
|
Loading…
x
Reference in New Issue
Block a user