From 69933b8659286b05bb00c09965c7318c5eb64814 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Thu, 25 Jan 2018 04:39:02 +0800 Subject: [PATCH] errors: improve the description of ERR_INVALID_ARG_VALUE - Allow user to customize why the argument is invalid - Display the argument with util.inspect so null bytes can be displayed properly. --- lib/internal/errors.js | 34 ++++++++++++++++++--------- test/parallel/test-internal-errors.js | 14 +++++++++-- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 058bbfac5d4896..5a3aaa04e97a09 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -23,9 +23,16 @@ const { kMaxLength } = process.binding('buffer'); const { defineProperty } = Object; // Lazily loaded -var util = null; +var util_ = null; var buffer; +function lazyUtil() { + if (!util_) { + util_ = require('util'); + } + return util_; +} + function makeNodeError(Base) { return class NodeError extends Base { constructor(key, ...args) { @@ -142,6 +149,7 @@ function createErrDiff(actual, expected, operator) { var lastPos = 0; var end = ''; var skipped = false; + const util = lazyUtil(); const actualLines = util .inspect(actual, { compact: false }).split('\n'); const expectedLines = util @@ -262,13 +270,11 @@ class AssertionError extends Error { if (message != null) { super(message); } else { - if (util === null) { - util = require('util'); - if (process.stdout.isTTY && process.stdout.getColorDepth() !== 1) { - green = '\u001b[32m'; - white = '\u001b[39m'; - red = '\u001b[31m'; - } + const util = lazyUtil(); + if (process.stdout.isTTY && process.stdout.getColorDepth() !== 1) { + green = '\u001b[32m'; + white = '\u001b[39m'; + red = '\u001b[31m'; } if (actual && actual.stack && actual instanceof Error) @@ -333,7 +339,7 @@ function message(key, args) { if (typeof msg === 'function') { fmt = msg; } else { - if (util === null) util = require('util'); + const util = lazyUtil(); fmt = util.format; if (args === undefined || args.length === 0) return msg; @@ -537,8 +543,14 @@ E('ERR_INSPECTOR_CLOSED', 'Session was closed'); E('ERR_INSPECTOR_NOT_AVAILABLE', 'Inspector is not available'); E('ERR_INSPECTOR_NOT_CONNECTED', 'Session is not connected'); E('ERR_INVALID_ARG_TYPE', invalidArgType); -E('ERR_INVALID_ARG_VALUE', (name, value) => - `The value "${String(value)}" is invalid for argument "${name}"`); +E('ERR_INVALID_ARG_VALUE', (name, value, reason = 'is invalid') => { + const util = lazyUtil(); + let inspected = util.inspect(value); + if (inspected.length > 128) { + inspected = inspected.slice(0, 128) + '...'; + } + return `The argument '${name}' ${reason}. Received ${inspected}`; +}), E('ERR_INVALID_ARRAY_LENGTH', (name, len, actual) => { internalAssert(typeof actual === 'number', 'actual must be a number'); diff --git a/test/parallel/test-internal-errors.js b/test/parallel/test-internal-errors.js index e8904bba0ec014..67c1cd1d2f045c 100644 --- a/test/parallel/test-internal-errors.js +++ b/test/parallel/test-internal-errors.js @@ -351,10 +351,20 @@ assert.strictEqual( } { - const error = new errors.Error('ERR_INVALID_ARG_VALUE', 'foo', 'bar'); + const error = new errors.Error('ERR_INVALID_ARG_VALUE', 'foo', '\u0000bar'); assert.strictEqual( error.message, - 'The value "bar" is invalid for argument "foo"' + 'The argument \'foo\' is invalid. Received \'\\u0000bar\'' + ); +} + +{ + const error = new errors.Error( + 'ERR_INVALID_ARG_VALUE', + 'foo', { a: 1 }, 'must have property \'b\''); + assert.strictEqual( + error.message, + 'The argument \'foo\' must have property \'b\'. Received { a: 1 }' ); }