diff options
author | Ruben Bridgewater <ruben@bridgewater.de> | 2019-09-23 18:22:10 +0300 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2019-10-03 22:34:44 +0300 |
commit | 500720f5781b96147422614b82c1f85e22d6a6e8 (patch) | |
tree | b09135e15cada8813afbc39ba3d56db308e1b17c /lib | |
parent | 6ea51bc4918c05e293c30d5efc384a15ae6cfd7e (diff) |
errors: make sure all Node.js errors show their properties
This improves Node.js errors by always showing the attached properties
when inspecting such an error. This applies especially to SystemError.
It did often not show any properties but now all properties will be
visible.
This is done in a mainly backwards compatible way. Instead of using
prototype getters and setters, the property is now set directly on the
error.
PR-URL: https://github.com/nodejs/node/pull/29677
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/internal/errors.js | 139 |
1 files changed, 67 insertions, 72 deletions
diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 8bfe3acb7b4..eb3c435b20e 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -12,8 +12,6 @@ const { Object, Math } = primordials; -const kCode = Symbol('code'); -const kInfo = Symbol('info'); const messages = new Map(); const codes = {}; @@ -121,76 +119,86 @@ class SystemError extends Error { writable: true, configurable: true }); - Object.defineProperty(this, kInfo, { - configurable: false, - enumerable: false, - value: context - }); - Object.defineProperty(this, kCode, { - configurable: true, - enumerable: false, - value: key, - writable: true - }); addCodeToName(this, 'SystemError', key); - } - get code() { - return this[kCode]; - } + this.code = key; - set code(value) { - Object.defineProperty(this, 'code', { - configurable: true, + Object.defineProperty(this, 'info', { + value: context, enumerable: true, - value, - writable: true + configurable: true, + writable: false }); - } - - get info() { - return this[kInfo]; - } - get errno() { - return this[kInfo].errno; - } - - set errno(val) { - this[kInfo].errno = val; - } - - get syscall() { - return this[kInfo].syscall; - } - - set syscall(val) { - this[kInfo].syscall = val; - } - - get path() { - return this[kInfo].path !== undefined ? - this[kInfo].path.toString() : undefined; - } + Object.defineProperty(this, 'errno', { + get() { + return context.errno; + }, + set: (value) => { + context.errno = value; + }, + enumerable: true, + configurable: true + }); - set path(val) { - this[kInfo].path = val ? - lazyBuffer().from(val.toString()) : undefined; - } + Object.defineProperty(this, 'syscall', { + get() { + return context.syscall; + }, + set: (value) => { + context.syscall = value; + }, + enumerable: true, + configurable: true + }); - get dest() { - return this[kInfo].path !== undefined ? - this[kInfo].dest.toString() : undefined; - } + if (context.path !== undefined) { + // TODO(BridgeAR): Investigate why and when the `.toString()` was + // introduced. The `path` and `dest` properties in the context seem to + // always be of type string. We should probably just remove the + // `.toString()` and `Buffer.from()` operations and set the value on the + // context as the user did. + Object.defineProperty(this, 'path', { + get() { + return context.path != null ? + context.path.toString() : context.path; + }, + set: (value) => { + context.path = value ? + lazyBuffer().from(value.toString()) : undefined; + }, + enumerable: true, + configurable: true + }); + } - set dest(val) { - this[kInfo].dest = val ? - lazyBuffer().from(val.toString()) : undefined; + if (context.dest !== undefined) { + Object.defineProperty(this, 'dest', { + get() { + return context.dest != null ? + context.dest.toString() : context.dest; + }, + set: (value) => { + context.dest = value ? + lazyBuffer().from(value.toString()) : undefined; + }, + enumerable: true, + configurable: true + }); + } } toString() { return `${this.name} [${this.code}]: ${this.message}`; } + + [Symbol.for('nodejs.util.inspect.custom')](recurseTimes, ctx) { + return lazyInternalUtilInspect().inspect(this, { + ...ctx, + getters: true, + customInspect: false + }); + } } function makeSystemErrorWithCode(key) { @@ -221,19 +229,7 @@ function makeNodeErrorWithCode(Base, key) { configurable: true }); addCodeToName(this, super.name, key); - } - - get code() { - return key; - } - - set code(value) { - Object.defineProperty(this, 'code', { - configurable: true, - enumerable: true, - value, - writable: true - }); + this.code = key; } toString() { @@ -394,7 +390,6 @@ function uvException(ctx) { err[prop] = ctx[prop]; } - // TODO(BridgeAR): Show the `code` property as part of the stack. err.code = code; if (path) { err.path = path; |