Permalink
Browse files

errors: make `code` and `name` properties settable

For internal errors, make `code` and `name` settable while keeping them
non-own properties by default.

PR-URL: #15694
Fixes: #15658
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
  • Loading branch information...
jdalton authored and Trott committed Oct 1, 2017
1 parent 6e172be commit 42a2a9badb6974e47b98aaee052e9710f34b93e8
Showing with 69 additions and 31 deletions.
  1. +30 −6 lib/internal/errors.js
  2. +39 −25 test/parallel/test-internal-errors.js
View
@@ -11,9 +11,8 @@
const kCode = Symbol('code');
const messages = new Map();
const {
kMaxLength
} = process.binding('buffer');
const { kMaxLength } = process.binding('buffer');
const { defineProperty } = Object;
// Lazily loaded
var util = null;
@@ -22,11 +21,36 @@ function makeNodeError(Base) {
return class NodeError extends Base {
constructor(key, ...args) {
super(message(key, args));
this[kCode] = this.code = key;
Object.defineProperty(this, 'name', {
defineProperty(this, kCode, {
configurable: true,
enumerable: false,
value: `${super.name} [${this[kCode]}]`,
value: key,
writable: true
});
}
get name() {
return `${super.name} [${this[kCode]}]`;
}
set name(value) {
defineProperty(this, 'name', {
configurable: true,
enumerable: true,
value,
writable: true
});
}
get code() {
return this[kCode];
}
set code(value) {
defineProperty(this, 'code', {
configurable: true,
enumerable: true,
value,
writable: true
});
}
@@ -307,38 +307,52 @@ assert.strictEqual(
{
const myError = new errors.Error('ERR_TLS_HANDSHAKE_TIMEOUT');
assert.strictEqual(myError.code, 'ERR_TLS_HANDSHAKE_TIMEOUT');
assert.strictEqual(myError.hasOwnProperty('code'), false);
assert.strictEqual(myError.hasOwnProperty('name'), false);
assert.deepStrictEqual(Object.keys(myError), []);
const initialName = myError.name;
myError.code = 'FHQWHGADS';
assert.strictEqual(myError.code, 'FHQWHGADS');
assert.strictEqual(myError.name, initialName);
assert.deepStrictEqual(Object.keys(myError), ['code']);
assert.ok(myError.name.includes('ERR_TLS_HANDSHAKE_TIMEOUT'));
assert.ok(!myError.name.includes('FHQWHGADS'));
}
// Test that `name` and `message` are mutable and that changing them alters
// `toString()` but not `console.log()` results, which is the behavior of
// `Error` objects in the browser.
// Test that `name` is mutable and that changing it alters `toString()` but not
// `console.log()` results, which is the behavior of `Error` objects in the
// browser. Note that `name` becomes enumerable after being assigned.
{
function test(prop) {
let initialConsoleLog = '';
common.hijackStdout((data) => { initialConsoleLog += data; });
const myError = new errors.Error('ERR_TLS_HANDSHAKE_TIMEOUT');
const initialToString = myError.toString();
console.log(myError);
assert.notStrictEqual(initialConsoleLog, '');
common.restoreStdout();
let subsequentConsoleLog = '';
common.hijackStdout((data) => { subsequentConsoleLog += data; });
myError[prop] = 'Fhqwhgads';
assert.notStrictEqual(myError.toString(), initialToString);
console.log(myError);
assert.strictEqual(subsequentConsoleLog, initialConsoleLog);
common.restoreStdout();
}
test('name');
test('message');
const myError = new errors.Error('ERR_TLS_HANDSHAKE_TIMEOUT');
assert.deepStrictEqual(Object.keys(myError), []);
const initialToString = myError.toString();
myError.name = 'Fhqwhgads';
assert.deepStrictEqual(Object.keys(myError), ['name']);
assert.notStrictEqual(myError.toString(), initialToString);
}
// Test that `message` is mutable and that changing it alters `toString()` but
// not `console.log()` results, which is the behavior of `Error` objects in the
// browser. Note that `message` remains non-enumerable after being assigned.
{
let initialConsoleLog = '';
common.hijackStdout((data) => { initialConsoleLog += data; });
const myError = new errors.Error('ERR_TLS_HANDSHAKE_TIMEOUT');
assert.deepStrictEqual(Object.keys(myError), []);
const initialToString = myError.toString();
console.log(myError);
assert.notStrictEqual(initialConsoleLog, '');
common.restoreStdout();
let subsequentConsoleLog = '';
common.hijackStdout((data) => { subsequentConsoleLog += data; });
myError.message = 'Fhqwhgads';
assert.deepStrictEqual(Object.keys(myError), []);
assert.notStrictEqual(myError.toString(), initialToString);
console.log(myError);
assert.strictEqual(subsequentConsoleLog, initialConsoleLog);
common.restoreStdout();
}

0 comments on commit 42a2a9b

Please sign in to comment.