From f044b21099f1fc01b326006866d4076514e83d5f Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Mon, 15 Apr 2019 20:10:17 +0200 Subject: [PATCH] process: inspect error in case of a fatal exception 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). --- lib/internal/process/execution.js | 7 ++++++- test/message/assert_throws_stack.out | 18 +++++++++++++++++- test/message/error_exit.out | 8 +++++++- test/message/if-error-has-good-stack.out | 18 +++++++++++++++++- test/message/stack_overflow.out | 2 +- test/message/throw_custom_error.out | 2 +- test/message/throw_in_line_with_tabs.out | 2 +- test/message/throw_non_error.out | 2 +- test/parallel/test-error-reporting.js | 2 +- test/pseudo-tty/test-fatal-error.js | 10 ++++++++++ test/pseudo-tty/test-fatal-error.out | 14 ++++++++++++++ 11 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 test/pseudo-tty/test-fatal-error.js create mode 100644 test/pseudo-tty/test-fatal-error.out diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index c95567c506237f..145189d84de25b 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -138,8 +138,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; @@ -153,6 +157,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. } diff --git a/test/message/assert_throws_stack.out b/test/message/assert_throws_stack.out index 7d4a7aecbcd410..e9f9cc5e891c37 100644 --- a/test/message/assert_throws_stack.out +++ b/test/message/assert_throws_stack.out @@ -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. (*assert_throws_stack.js:*:*) + at * + at * + at * + at * + at * + at *, + expected: [Object], + operator: 'throws' +} diff --git a/test/message/error_exit.out b/test/message/error_exit.out index b975d41a55d929..a0d848b125b7a6 100644 --- a/test/message/error_exit.out +++ b/test/message/error_exit.out @@ -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' +} diff --git a/test/message/if-error-has-good-stack.out b/test/message/if-error-has-good-stack.out index c762d74aedbca2..87261c451fff1e 100644 --- a/test/message/if-error-has-good-stack.out +++ b/test/message/if-error-has-good-stack.out @@ -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. (*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' +} diff --git a/test/message/stack_overflow.out b/test/message/stack_overflow.out index c83f8001d99f1f..d7a2c3eef06e01 100644 --- a/test/message/stack_overflow.out +++ b/test/message/stack_overflow.out @@ -3,4 +3,4 @@ before JSON.stringify(array); ^ -RangeError: Maximum call stack size exceeded +[RangeError: Maximum call stack size exceeded] diff --git a/test/message/throw_custom_error.out b/test/message/throw_custom_error.out index 0c6b9d128c9095..a1fa8c6c5b71ff 100644 --- a/test/message/throw_custom_error.out +++ b/test/message/throw_custom_error.out @@ -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' } diff --git a/test/message/throw_in_line_with_tabs.out b/test/message/throw_in_line_with_tabs.out index 89a81beb4126d1..9392ef5cca279a 100644 --- a/test/message/throw_in_line_with_tabs.out +++ b/test/message/throw_in_line_with_tabs.out @@ -2,4 +2,4 @@ before *test*message*throw_in_line_with_tabs.js:* throw ({ foo: 'bar' }); ^ -[object Object] +{ foo: 'bar' } diff --git a/test/message/throw_non_error.out b/test/message/throw_non_error.out index 2b7e0120b6f987..a744f786ca6dee 100644 --- a/test/message/throw_non_error.out +++ b/test/message/throw_non_error.out @@ -1,4 +1,4 @@ *test*message*throw_non_error.js:* throw ({ foo: 'bar' }); ^ -[object Object] +{ foo: 'bar' } diff --git a/test/parallel/test-error-reporting.js b/test/parallel/test-error-reporting.js index f56f1e4bdca67d..7568206d46bd00 100644 --- a/test/parallel/test-error-reporting.js +++ b/test/parallel/test-error-reporting.js @@ -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(/ (*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 +}