Last active
November 5, 2020 13:49
-
-
Save mearns/22969f35e9e1ec57daa14a2a20d7e026 to your computer and use it in GitHub Desktop.
Error Utilities for JavaScript (NodeJS)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Create a new Error to wrap another Error. | |
* | |
* @params {Error} cause The error you want to wrap | |
* @params {string} [name] Optionally specify the `name` property for the error. You can also | |
* specify a `name` property in the `props` arg. If neither is given, the name of the given `cause` is | |
* used. | |
* @params {string} [message] Optionally specify the `message` property for the error. You can also | |
* specify a `message` property in the `props` arg. If neither is given, the `message` of the given `cause` is | |
* used. | |
* @params {object} [props] Optionally specify an object of properties to attach to the generated error. | |
*/ | |
function wrapError(cause, name = null, message = null, props = {}) { | |
const newError = Object.assign( | |
new Error(message || props.message || cause.message), | |
cause, | |
props, | |
{ | |
cause, | |
errors: [ | |
cause | |
] | |
} | |
); | |
newError.name = name || props.name || cause.name; | |
if (typeof Error.captureStackTrace === "function") { | |
Error.captureStackTrace(newError, wrapError); | |
} | |
return newError; | |
} | |
/** | |
* This is useful if your logging tool doesn't have special handling of Error values, because the 3 key properties | |
* of an Error---name, message, and stack---are not enumerable by default, so if you're iterating over the enumerable | |
* properties, using `JSON.stringify` for instance, you won't actually get any of those properties. | |
* | |
* Note that it actually **mutates** the given object, it doesn't return a new object. Also note that if the given | |
* object has a magic-getter configured for the `name` property, that will be **replaced** with the next value returned | |
* by that getter. | |
*/ | |
function makeErrorVisible(error) { | |
Object.defineProperty(error, "name", { ...Object.getOwnPropertyDescriptor(error, "name"), enumerable: true, value: error.name }); | |
Object.defineProperty(error, "message", { ...Object.getOwnPropertyDescriptor(error, "message"), enumerable: true }); | |
Object.defineProperty(error, "stack", { ...Object.getOwnPropertyDescriptor(error, "stack"), enumerable: true }); | |
return error; | |
} |
Awesome, thanks @blicksky! That's definitely relevant. I can't really decide how much overlap there is: definitely a good amount, and it might be effectively a replacement for wrapError
. It makes me think that at least wrapError
could set newError.errors = [cause]
, either instead of or in addition to the .cause
property, to match the interface.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm not sure if this serves the same purpose, but
AggregateError
is at least related: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError. It was added in V8 8.5, which is included in Node 15: https://nodejs.medium.com/node-js-v15-0-0-is-here-deb00750f278.