-
Notifications
You must be signed in to change notification settings - Fork 30.2k
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
process: split routines used to enhance fatal exception stack traces #28308
Changes from all commits
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 |
---|---|---|
|
@@ -622,6 +622,45 @@ function addNumericalSeparator(val) { | |
return `${val.slice(0, i)}${res}`; | ||
} | ||
|
||
// Used to enhance the stack that will be picked up by the inspector | ||
const kEnhanceStackBeforeInspector = Symbol('kEnhanceStackBeforeInspector'); | ||
|
||
// These are supposed to be called only on fatal exceptions before | ||
// the process exits. | ||
const fatalExceptionStackEnhancers = { | ||
beforeInspector(error) { | ||
if (typeof error[kEnhanceStackBeforeInspector] !== 'function') { | ||
return error.stack; | ||
} | ||
|
||
try { | ||
// Set the error.stack here so it gets picked up by the | ||
// inspector. | ||
error.stack = error[kEnhanceStackBeforeInspector](); | ||
} catch { | ||
// We are just enhancing the error. If it fails, ignore it. | ||
} | ||
return error.stack; | ||
}, | ||
afterInspector(error) { | ||
const originalStack = error.stack; | ||
const { | ||
inspect, | ||
inspectDefaultOptions: { | ||
colors: defaultColors | ||
} | ||
} = lazyInternalUtilInspect(); | ||
const colors = internalBinding('util').guessHandleType(2) === 'TTY' && | ||
require('internal/tty').hasColors() || | ||
defaultColors; | ||
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. On the windows issue: we could temporarily disable the coloring by adding |
||
try { | ||
return inspect(error, { colors }); | ||
} catch { | ||
return originalStack; | ||
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. Note that here we don't patch Ideally we could also just pass structured data (e.g. 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. Can't we do this in a WeakMap? Their point is extending things from the outside after all 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 don't think we need a WeakMap for this, as this is kind of a one-off thing so there is no mapping necessary. We only need to pass a separate object around, the association between the error and the object can already be known from how they are passed around, and we probably don't need an equivalent of 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. (Also now that you mentioned it...I believe V8 still does not have embedder API to interface with WeakMaps? That's why we still have to create our ESM module wrap map in JS land) |
||
} | ||
} | ||
}; | ||
|
||
module.exports = { | ||
addCodeToName, // Exported for NghttpError | ||
codes, | ||
|
@@ -638,6 +677,8 @@ module.exports = { | |
// This is exported only to facilitate testing. | ||
E, | ||
prepareStackTrace, | ||
kEnhanceStackBeforeInspector, | ||
fatalExceptionStackEnhancers | ||
}; | ||
|
||
// To declare an error message, use the E(sym, val, def) function above. The sym | ||
|
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.
Ideally we probably should not even have to do this, instead we can just return a string to some API and leave the
error.stack
intact, because patchingerror.stack
(which is just a randomly formatted string) over and over is error-prone, especially in the presence ofError.prepareStackTrace
...but there does not seem to be a hook to customize the stack trace in the console message logged by the inspector.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.
Yeah and error.stack might not be writeable, (should be fine in this case)