@sprucelabs/error
Version:
Error reporting that's really, really helpful. 💡
117 lines (116 loc) • 4.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
Error.stackTraceLimit = Infinity;
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 = { ...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 = { ...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: {
...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),
});
}
}
}
exports.default = AbstractSpruceError;
class GenericOriginalError extends AbstractSpruceError {
}