Skip to content

Commit

Permalink
errors: make code and name properties settable
Browse files Browse the repository at this point in the history
For internal errors, make `code` and `name` settable while keeping them
non-own properties by default.

PR-URL: nodejs#15694
Fixes: nodejs#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 12, 2017
1 parent eb7c6dc commit d4436a0
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 25 deletions.
33 changes: 30 additions & 3 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,45 @@
const kCode = Symbol('code');
const messages = new Map();

const { defineProperty } = Object;

// Lazily loaded
var util = null;

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
});
}
Expand Down
58 changes: 36 additions & 22 deletions test/parallel/test-internal-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,40 +240,54 @@ assert.throws(
// Test that `code` property is mutable and that changing it does not change the
// name.
{
const myError = new errors.Error('ERR_MISSING_ARGS', ['name']);
const myError = new errors.Error('ERR_MISSING_ARGS', ['Sterrance']);
assert.strictEqual(myError.code, 'ERR_MISSING_ARGS');
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_MISSING_ARGS'));
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_MISSING_ARGS', ['name']);
const initialToString = myError.toString();
console.log(myError);
assert.notStrictEqual(initialConsoleLog, '');
const myError = new errors.Error('ERR_MISSING_ARGS', ['Sterrance']);
assert.deepStrictEqual(Object.keys(myError), []);
const initialToString = myError.toString();

common.restoreStdout();
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_MISSING_ARGS', ['Sterrance']);
assert.deepStrictEqual(Object.keys(myError), []);
const initialToString = myError.toString();
console.log(myError);
assert.notStrictEqual(initialConsoleLog, '');

let subsequentConsoleLog = '';
common.hijackStdout((data) => { subsequentConsoleLog += data; });
myError[prop] = 'Fhqwhgads';
assert.notStrictEqual(myError.toString(), initialToString);
console.log(myError);
assert.strictEqual(subsequentConsoleLog, initialConsoleLog);
common.restoreStdout();

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);

test('name');
test('message');
common.restoreStdout();
}

0 comments on commit d4436a0

Please sign in to comment.