@mdf.js/crash
Version:
MMS - API Crash - Enhanced error management library
159 lines • 5.65 kB
JavaScript
;
/**
* Copyright 2024 Mytra Control S.L. All rights reserved.
*
* Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
* or at https://opensource.org/licenses/MIT.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Crash = void 0;
const uuid_1 = require("uuid");
const BaseError_1 = require("../BaseError");
const Multi_1 = require("../Multi");
/**
* Improved handling of standard errors.
*
* Crash helps us manage standard errors within our application by providing us with some tools:
* - Association of errors and their causes in a hierarchical way.
* - Simple search for root causes within the hierarchy of errors.
* - Stack management, both of the current instance of the error, and of the causes.
* - Facilitate error logging.
*
* In addition, in combination with the Multi error types, errors in validation processes, and Boom,
* errors for the REST-API interfaces, it allows a complete management of the different types of
* errors in our backend.
* @category Crash
* @public
*/
class Crash extends BaseError_1.Base {
/**
* Check if an object is a valid Crash or Multi error
* @param error - error to be checked
* @param uuid - Optional uuid to be used instead of a random one.
* @returns
*/
static from(error, uuid) {
if (error instanceof Crash || error instanceof Multi_1.Multi) {
return error;
}
else if (error instanceof Error) {
return new Crash(error.message, uuid !== null && uuid !== void 0 ? uuid : (0, uuid_1.v4)(), { name: error.name });
}
else if (typeof error === 'string') {
return new Crash(error, uuid !== null && uuid !== void 0 ? uuid : (0, uuid_1.v4)());
}
else if (error &&
typeof error === 'object' &&
typeof error['message'] === 'string') {
return new Crash(error['message']);
}
else {
return new Crash(`Unexpected error type`, uuid !== null && uuid !== void 0 ? uuid : (0, uuid_1.v4)(), {
info: { error },
});
}
}
constructor(message, uuid, options) {
var _a;
super(message, uuid, options);
/** Crash error */
this._isCrash = true;
// *****************************************************************************************
// #region options type safe
if ((_a = this._options) === null || _a === void 0 ? void 0 : _a['cause']) {
if (this._options['cause'] instanceof Crash || this._options['cause'] instanceof Error) {
this._cause = this._options['cause'];
}
else {
throw new BaseError_1.Base('Parameter cause must be an Error/Crash', uuid);
}
}
// #endregion
if (this.name === 'BaseError') {
this.name = 'CrashError';
}
}
/** Determine if this instance is a Crash error */
get isCrash() {
return this._isCrash;
}
/** Cause source of error */
get cause() {
return this._cause;
}
/** Get the trace of this hierarchy of errors */
trace() {
const trace = [];
let cause = this._cause;
while (cause) {
if (cause instanceof Multi_1.Multi) {
trace.push(`caused by ${cause.toString()}`);
if (cause.causes) {
trace.push(...cause.causes.map(entry => `failed with ${entry.toString()}`));
}
cause = undefined;
}
else if (cause instanceof Crash) {
trace.push(`caused by ${cause.toString()}`);
cause = cause.cause;
}
else {
trace.push(`caused by ${cause.name}: ${cause.message}`);
cause = undefined;
}
}
trace.unshift(this.toString());
return trace;
}
/**
* Look in the nested causes of the error and return the first occurrence of a cause with the
* indicated name
* @param name - name of the error to search for
* @returns the cause, if there is any present with that name
*/
findCauseByName(name) {
let cause = this._cause;
while (cause) {
if (cause.name === name) {
return cause;
}
else if (cause instanceof Crash) {
cause = cause.cause;
}
else {
return undefined;
}
}
return undefined;
}
/**
* Check if there is any cause in the stack with the indicated name
* @param name - name of the error to search for
* @returns Boolean value as the result of the search
*/
hasCauseWithName(name) {
return this.findCauseByName(name) !== undefined;
}
/**
* Returns a full stack of the error and causes hierarchically. The string contains the
* description of the point in the code at which the Error/Crash was instantiated
*/
fullStack() {
if (this._cause instanceof Crash) {
return `${this.stack}\ncaused by ${this._cause.fullStack()}`;
}
else if (this._cause instanceof Error) {
return `${this.stack}\ncaused by ${this._cause.stack}`;
}
return this.stack;
}
/** Return Crash error in JSON format */
toJSON() {
return {
...super.toObject(),
trace: this.trace(),
};
}
}
exports.Crash = Crash;
//# sourceMappingURL=CrashError.js.map