util: improve error inspection

When inspecting errors with extra properties while setting the
compact option to false, it will now return:

[Error: foo] {
    at repl:1:5
    at Script.runInThisContext (vm.js:89:20)
  bla: true
}

Instead of:

Error: foo
    at repl:1:5
    at Script.runInThisContext (vm.js:91:20) {
  bla: true
}

PR-URL: https://github.com/nodejs/node/pull/20802
Refs: https://github.com/nodejs/node/issues/20253
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
Ruben Bridgewater 2018-05-17 13:20:27 +02:00
parent e852289802
commit c041a2ee5b
No known key found for this signature in database
GPG Key ID: F07496B3EB3C1762
3 changed files with 48 additions and 4 deletions

View File

@ -587,7 +587,8 @@ function formatValue(ctx, value, recurseTimes) {
// Make error with message first say the error
base = formatError(value);
// Wrap the error in brackets in case it has no stack trace.
if (base.indexOf('\n at') === -1) {
const stackStart = base.indexOf('\n at');
if (stackStart === -1) {
base = `[${base}]`;
}
// The message and the stack have to be indented as well!
@ -597,6 +598,11 @@ function formatValue(ctx, value, recurseTimes) {
}
if (keyLength === 0)
return base;
if (ctx.compact === false && stackStart !== -1) {
braces[0] += `${base.slice(stackStart)}`;
base = `[${base.slice(0, stackStart)}]`;
}
} else if (isAnyArrayBuffer(value)) {
// Fast path for ArrayBuffer and SharedArrayBuffer.
// Can't do the same for DataView because it has a non-primitive

View File

@ -174,7 +174,7 @@ function testError() {
// The error, both from the original throw and the `_error` echo.
'Error: foo',
'Error: foo',
'[Error: foo]',
// The sync error, with individual property echoes
/Error: ENOENT: no such file or directory, scandir '.*nonexistent.*'/,

View File

@ -519,11 +519,49 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324');
const tmp = Error.stackTraceLimit;
Error.stackTraceLimit = 0;
const err = new Error('foo');
assert.strictEqual(util.inspect(err), '[Error: foo]');
const err2 = new Error('foo\nbar');
assert.strictEqual(util.inspect(err, { compact: true }), '[Error: foo]');
assert(err.stack);
delete err.stack;
assert(!err.stack);
assert.strictEqual(util.inspect(err), '[Error: foo]');
assert.strictEqual(util.inspect(err, { compact: true }), '[Error: foo]');
assert.strictEqual(
util.inspect(err2, { compact: true }),
'[Error: foo\nbar]'
);
err.bar = true;
err2.bar = true;
assert.strictEqual(
util.inspect(err, { compact: true }),
'{ [Error: foo] bar: true }'
);
assert.strictEqual(
util.inspect(err2, { compact: true }),
'{ [Error: foo\nbar] bar: true }'
);
assert.strictEqual(
util.inspect(err, { compact: true, breakLength: 5 }),
'{ [Error: foo]\n bar: true }'
);
assert.strictEqual(
util.inspect(err, { compact: true, breakLength: 1 }),
'{ [Error: foo]\n bar:\n true }'
);
assert.strictEqual(
util.inspect(err2, { compact: true, breakLength: 5 }),
'{ [Error: foo\nbar]\n bar: true }'
);
assert.strictEqual(
util.inspect(err, { compact: false }),
'[Error: foo] {\n bar: true\n}'
);
assert.strictEqual(
util.inspect(err2, { compact: false }),
'[Error: foo\nbar] {\n bar: true\n}'
);
Error.stackTraceLimit = tmp;
}