-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Promises/better unhandled rejection message #17158
Changes from 2 commits
a29fe91
ba4adc5
ab45e60
bf06851
9d29f0c
481c7f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
'use strict'; | ||
|
||
const { safeToString } = process.binding('util'); | ||
|
||
const promiseRejectEvent = process._promiseRejectEvent; | ||
const hasBeenNotifiedProperty = new WeakMap(); | ||
const promiseToGuidProperty = new WeakMap(); | ||
|
@@ -60,11 +58,23 @@ function setupPromises(scheduleMicrotasks) { | |
} | ||
|
||
function emitWarning(uid, reason) { | ||
try { | ||
if (reason instanceof Error) { | ||
process.emitWarning(reason.stack, 'UnhandledPromiseRejectionWarning'); | ||
} else { | ||
process.emitWarning(reason, 'UnhandledPromiseRejectionWarning'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this still should be
P.S. could you add a test for a non string rejection? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the expected behavior when strings get rejected? I couldn't find a way to get the stack trace in that case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd assume the stack has been destroyed when this is reached. IMHO just printing the reason (after stringifying) is the best we can do. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that I've pushed the commit to wrap the reason with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah it's an awkward test... You could add a line just before last: const p = Promise.reject(100); then move case (2) to (3) add a case (2):
P.S. it's testing Strings because it checks the stringified output There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @refack Added the requested test, also added comments to make it clear what each state in the state machine means. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💯 |
||
} | ||
} catch (e) { | ||
// ignored | ||
} | ||
|
||
const warning = new Error( | ||
`Unhandled promise rejection (rejection id: ${uid}): ` + | ||
safeToString(reason)); | ||
'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(). ' + | ||
`(rejection id: ${uid})` | ||
); | ||
warning.name = 'UnhandledPromiseRejectionWarning'; | ||
warning.id = uid; | ||
try { | ||
if (reason instanceof Error) { | ||
warning.stack = reason.stack; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,18 +12,21 @@ let b = 0; | |
process.on('warning', common.mustCall((warning) => { | ||
switch (b++) { | ||
case 0: | ||
assert.strictEqual(warning.name, 'UnhandledPromiseRejectionWarning'); | ||
assert(/Unhandled promise rejection/.test(warning.message)); | ||
assert.strictEqual(warning.message, 'This was rejected'); | ||
break; | ||
case 1: | ||
assert.strictEqual(warning.name, 'DeprecationWarning'); | ||
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.'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these lines need to be line-wrapped at <= 80 chars There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How come |
||
break; | ||
case 2: | ||
assert.strictEqual(warning.name, 'DeprecationWarning'); | ||
break; | ||
case 3: | ||
assert.strictEqual(warning.name, 'PromiseRejectionHandledWarning'); | ||
assert(/Promise rejection was handled asynchronously/ | ||
.test(warning.message)); | ||
} | ||
}, 3)); | ||
}, 4)); | ||
|
||
const p = Promise.reject('This was rejected'); | ||
setImmediate(common.mustCall(() => p.catch(() => {}))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I guess the only downfall to doing it this way is it won't include any additional properties added on to the Error object. Any reason to do this vs using
util.inspect()
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just that I wasn't aware of
util.inspect()
. I went with what the rest of the code did in the same function.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Namely, Node doesn't show this information for synchronous errors: