UNPKG

@sprucelabs/error

Version:

Error reporting that's really, really helpful. 💡

111 lines (110 loc) • 4.02 kB
Error.stackTraceLimit = Infinity; export default class AbstractSpruceError extends Error { constructor(options) { const { code } = options; super(code); this.options = options; const env = typeof process !== 'undefined' && process.env ? process.env : {}; const key = `FRIENDLY_ERROR_MESSAGE_${code}`; this.options.friendlyMessage = env[key] ? env[key] : this.options.friendlyMessage; if (options.originalError) { if (options.originalError instanceof Error) { this.originalError = options.originalError; //@ts-ignore } else if (options.originalError.isJavascriptError) { //@ts-ignore this.originalError = new Error(options.originalError.message); //@ts-ignore this.originalError.name = options.originalError.name; //@ts-ignore this.originalError.stack = options.originalError.stack; //@ts-ignore } else if (options.originalError && options.originalError.options) { this.originalError = new GenericOriginalError( //@ts-ignore options.originalError.options); } } this.message = this.friendlyMessage(); const optionsWithoutCode = Object.assign({}, options); //@ts-ignore delete optionsWithoutCode.code; delete optionsWithoutCode.originalError; this.stack = this.stack + '\n\nOptions: ' + JSON.stringify(optionsWithoutCode, null, 2); } friendlyMessage() { return this.options.friendlyMessage || this.message; } toString() { return this.toJson(); } serializeOriginalError(options) { let serializedOptions = Object.assign({}, options); if (!(serializedOptions.originalError instanceof AbstractSpruceError) && serializedOptions.originalError instanceof Error) { serializedOptions.originalError = { //@ts-ignore isJavascriptError: true, message: serializedOptions.originalError.message, stack: serializedOptions.originalError.stack, name: serializedOptions.originalError.name, }; } return serializedOptions; } toJson() { return JSON.stringify(this.toObject()); } toObject() { const obj = { options: Object.assign(Object.assign({}, this.serializeOriginalError(this.options)), { friendlyMessage: this.friendlyMessage() }), }; if (this.stack) { obj.stack = this.stack; } return obj; } prettyPrint() { return this.message + '\n\n' + this.stack; } static parse(json, ClassRef) { if (json instanceof AbstractSpruceError) { return json; } if (json instanceof Error) { //@ts-ignore const err = new ClassRef({ code: 'UNKNOWN_ERROR', friendlyMessage: json.message, originalError: json, }); err.stack = json.stack; return err; } try { const { options, stack } = typeof json === 'string' ? JSON.parse(json) : json; // @ts-ignore const err = new ClassRef(options); err.stack = stack; return err; } catch (err) { const stringified = typeof json === 'string' ? json : JSON.stringify(json); // @ts-ignore return new ClassRef({ code: 'UNKNOWN_ERROR', friendlyMessage: `I was not able to parse an incoming error. Original message is ${stringified}.`, originalError: new Error(stringified), }); } } } class GenericOriginalError extends AbstractSpruceError { }