61 lines
2.0 KiB
JavaScript
61 lines
2.0 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
// via https://stackoverflow.com/a/42755876/796832
|
||
|
|
||
|
// Standard error extender from @deployable/errors
|
||
|
class ExtendedError extends Error {
|
||
|
constructor(message) {
|
||
|
super(message);
|
||
|
this.name = this.constructor.name;
|
||
|
this.message = message;
|
||
|
if (typeof Error.captureStackTrace === 'function') {
|
||
|
Error.captureStackTrace(this, this.constructor);
|
||
|
} else {
|
||
|
this.stack = new Error(message).stack;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// A way to create a new error with a custom message but keep the stack trace of
|
||
|
// the original error. Useful to give more context and why the action was tried
|
||
|
// in the first place.
|
||
|
//
|
||
|
// For example, if you get a generic EACCES disk error of a certain file, you
|
||
|
// want to know why and what context the disk was trying to be read. A
|
||
|
// stack-trace is not human digestable and only gives the where in the code.
|
||
|
// What I actually need to know is that I was trying to read the `ratelimit` key
|
||
|
// from the config when this error occured.
|
||
|
//
|
||
|
// `new RethrownError('Failed to get the ratelimit key from the config', originalError)` (failed to read the disk)
|
||
|
class RethrownError extends ExtendedError {
|
||
|
constructor(message, error) {
|
||
|
super(message);
|
||
|
if (!error) throw new Error('RethrownError requires a message and error');
|
||
|
this.original = error;
|
||
|
this.newStack = this.stack;
|
||
|
|
||
|
// The number of lines that make up the message itself. We count this by the
|
||
|
// number of `\n` and `+ 1` for the first line because it doesn't start with
|
||
|
// new line.
|
||
|
const messageLines = (this.message.match(/\n/g) || []).length + 1;
|
||
|
|
||
|
const indentedOriginalError = error.stack
|
||
|
.split('\n')
|
||
|
.map((line) => ` ${line}`)
|
||
|
.join('\n');
|
||
|
|
||
|
this.stack =
|
||
|
this.stack
|
||
|
.split('\n')
|
||
|
// We use `+ 1` here so that we include the first line of the stack to
|
||
|
// people know where the error was thrown from.
|
||
|
.slice(0, messageLines + 1)
|
||
|
.join('\n') +
|
||
|
'\n' +
|
||
|
' --- Original Error ---\n' +
|
||
|
indentedOriginalError;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = RethrownError;
|