summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Bridgewater <ruben.bridgewater@maibornwolff.de>2020-03-17 17:24:25 +0100
committerRuben Bridgewater <ruben.bridgewater@maibornwolff.de>2020-03-17 17:26:26 +0100
commita812ec7f9a100240385a6a4ead81469914addc89 (patch)
treec47e48abf26e23e9f5df9c925e8f775ebc569a88
parent40b559a376ae1db031132a86a76834decf6f0c2d (diff)
downloadnode-new-2020-03-17-hide-duplicated-error-properties.tar.gz
util: only inspect error properties that are not visible otherwise2020-03-17-hide-duplicated-error-properties
Inspecting errors results in duplicated information in case an error is created with enumerable `name`, `message` or `stack` properties. In that case, check if the output already contains that information and prevent listing that property. This reduces the noise as receiver.
-rw-r--r--lib/internal/util/inspect.js16
-rw-r--r--test/parallel/test-util-inspect.js22
2 files changed, 36 insertions, 2 deletions
diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js
index 42fefdd147..082d7c7d27 100644
--- a/lib/internal/util/inspect.js
+++ b/lib/internal/util/inspect.js
@@ -885,7 +885,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
return ctx.stylize(base, 'date');
}
} else if (isError(value)) {
- base = formatError(value, constructor, tag, ctx);
+ base = formatError(value, constructor, tag, ctx, keys);
if (keys.length === 0 && protoProps === undefined)
return base;
} else if (isAnyArrayBuffer(value)) {
@@ -1078,11 +1078,23 @@ function getFunctionBase(value, constructor, tag) {
return base;
}
-function formatError(err, constructor, tag, ctx) {
+function formatError(err, constructor, tag, ctx, keys) {
const name = err.name != null ? String(err.name) : 'Error';
let len = name.length;
let stack = err.stack ? String(err.stack) : ErrorPrototypeToString(err);
+ // Do not "duplicate" error properties that are already included in the output
+ // otherwise.
+ if (!ctx.showHidden && keys.length !== 0) {
+ for (const name of ['name', 'message', 'stack']) {
+ const index = keys.indexOf(name);
+ // Only hide the property in case it's part of the original stack
+ if (index !== -1 && stack.includes(err[name])) {
+ keys.splice(index, 1);
+ }
+ }
+ }
+
// A stack trace may contain arbitrary data. Only manipulate the output
// for "regular errors" (errors that "look normal") for now.
if (constructor === null ||
diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js
index 7fb677d495..40bc363877 100644
--- a/test/parallel/test-util-inspect.js
+++ b/test/parallel/test-util-inspect.js
@@ -696,6 +696,28 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324');
Error.stackTraceLimit = tmp;
}
+// Prevent enumerable error properties from being printed.
+{
+ let err = new Error();
+ err.message = 'foobar';
+ let out = util.inspect(err).split('\n');
+ assert.strictEqual(out[0], 'Error: foobar');
+ assert(out[out.length - 1].startsWith(' at '));
+ // Reset the error, the stack is otherwise not recreated.
+ err = new Error();
+ err.message = 'foobar';
+ err.name = 'Unique';
+ Object.defineProperty(err, 'stack', { value: err.stack, enumerable: true });
+ out = util.inspect(err).split('\n');
+ assert.strictEqual(out[0], 'Unique: foobar');
+ assert(out[out.length - 1].startsWith(' at '));
+ err.name = 'Baz';
+ out = util.inspect(err).split('\n');
+ assert.strictEqual(out[0], 'Unique: foobar');
+ assert.strictEqual(out[out.length - 2], " name: 'Baz'");
+ assert.strictEqual(out[out.length - 1], '}');
+}
+
// Doesn't capture stack trace.
{
function BadCustomError(msg) {