Skip to content

Commit

Permalink
process: inspect error in case of a fatal exception
Browse files Browse the repository at this point in the history
This makes sure that errors that shut down the application are
inspected with `util.inspect()`. That makes sure that all extra
properties on the error will be visible and also that the stack trace
is highlighted (Node.js internal frames will be grey and node modules
are underlined).

PR-URL: #27243
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
  • Loading branch information
BridgeAR authored and targos committed May 17, 2019
1 parent ea62f4a commit 0393045
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 9 deletions.
7 changes: 6 additions & 1 deletion lib/internal/process/execution.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,12 @@ function createFatalException() {
if (exceptionHandlerState.captureFn !== null) {
exceptionHandlerState.captureFn(er);
} else if (!process.emit('uncaughtException', er, type)) {
// If someone handled it, then great. otherwise, die in C++ land
// If someone handled it, then great. Otherwise, die in C++ land
// since that means that we'll exit the process, emit the 'exit' event.
const { inspect } = require('internal/util/inspect');
const colors = internalBinding('util').guessHandleType(2) === 'TTY' &&
require('internal/tty').hasColors() ||
inspect.defaultOptions.colors;
try {
if (!process._exiting) {
process._exiting = true;
Expand All @@ -157,6 +161,7 @@ function createFatalException() {
const { kExpandStackSymbol } = require('internal/util');
if (typeof er[kExpandStackSymbol] === 'function')
er[kExpandStackSymbol]();
er.stack = inspect(er, { colors });
} catch {
// Nothing to be done about it at this point.
}
Expand Down
18 changes: 17 additions & 1 deletion test/message/assert_throws_stack.out
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,20 @@ AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
at *
at *
at *
at *
at * {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: Error: foo
at assert.throws.bar (*assert_throws_stack.js:*)
at getActual (assert.js:*)
at Function.throws (assert.js:*)
at Object.<anonymous> (*assert_throws_stack.js:*:*)
at *
at *
at *
at *
at *
at *,
expected: [Object],
operator: 'throws'
}
8 changes: 7 additions & 1 deletion test/message/error_exit.out
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
at Module.load (internal/modules/cjs/loader.js:*:*)
at Function.Module._load (internal/modules/cjs/loader.js:*:*)
at Function.Module.runMain (internal/modules/cjs/loader.js:*:*)
at internal/main/run_main_module.js:*:*
at internal/main/run_main_module.js:*:* {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 1,
expected: 2,
operator: 'strictEqual'
}
18 changes: 17 additions & 1 deletion test/message/if-error-has-good-stack.out
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,20 @@ AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
at Module.load (internal/modules/cjs/loader.js:*:*)
at Function.Module._load (internal/modules/cjs/loader.js:*:*)
at Function.Module.runMain (internal/modules/cjs/loader.js:*:*)
at internal/main/run_main_module.js:*:*
at internal/main/run_main_module.js:*:* {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: Error: test error
at c (*if-error-has-good-stack.js:*:*)
at b (*if-error-has-good-stack.js:*:*)
at a (*if-error-has-good-stack.js:*:*)
at Object.<anonymous> (*if-error-has-good-stack.js:*:*)
at Module._compile (internal/modules/cjs/loader.js:*:*)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*)
at Module.load (internal/modules/cjs/loader.js:*:*)
at Function.Module._load (internal/modules/cjs/loader.js:*:*)
at Function.Module.runMain (internal/modules/cjs/loader.js:*:*)
at internal/main/run_main_module.js:*:*
expected: null,
operator: 'ifError'
}
2 changes: 1 addition & 1 deletion test/message/stack_overflow.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ before
JSON.stringify(array);
^

RangeError: Maximum call stack size exceeded
[RangeError: Maximum call stack size exceeded]
2 changes: 1 addition & 1 deletion test/message/throw_custom_error.out
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*test*message*throw_custom_error.js:*
throw ({ name: 'MyCustomError', message: 'This is a custom message' });
^
MyCustomError: This is a custom message
{ name: 'MyCustomError', message: 'This is a custom message' }
2 changes: 1 addition & 1 deletion test/message/throw_in_line_with_tabs.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ before
*test*message*throw_in_line_with_tabs.js:*
throw ({ foo: 'bar' });
^
[object Object]
{ foo: 'bar' }
2 changes: 1 addition & 1 deletion test/message/throw_non_error.out
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*test*message*throw_non_error.js:*
throw ({ foo: 'bar' });
^
[object Object]
{ foo: 'bar' }
2 changes: 1 addition & 1 deletion test/parallel/test-error-reporting.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,5 @@ errExec('throws_error6.js', common.mustCall((err, stdout, stderr) => {

// Object that throws in toString() doesn't print garbage
errExec('throws_error7.js', common.mustCall((err, stdout, stderr) => {
assert.ok(/<toString\(\) threw exception/.test(stderr));
assert.ok(/throw {\r?\n\^\r?\n{ toString: \[Function: toString] }\r?\n$/.test(stderr));
}));
10 changes: 10 additions & 0 deletions test/pseudo-tty/test-fatal-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';
require('../common');

const { inspect } = require('util');

inspect.defaultOptions.colors = true;

const err = new TypeError('foobar');
err.bla = true;
throw err;
14 changes: 14 additions & 0 deletions test/pseudo-tty/test-fatal-error.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
*test-fatal-error.js:*
throw err;
^

TypeError: foobar
at Object.<anonymous> (*test-fatal-error.js:*)
*[90m at *(internal*loader.js:*:*)*[39m
*[90m at *(internal*loader.js:*:*)*[39m
*[90m at *(internal*loader.js:*:*)*[39m
*[90m at *(internal*loader.js:*:*)*[39m
*[90m at *[39m
*[90m at *[39m {
bla: *[33mtrue*[39m
}

0 comments on commit 0393045

Please sign in to comment.