@mdf.js/crash
Version:
MMS - API Crash - Enhanced error management library
189 lines • 6.39 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Multi = void 0;
const BaseError_1 = require("../BaseError");
const Crash_1 = require("../Crash");
/**
* Improved handling of validation errors.
*
* Multi helps us to manage validation or information transformation errors, in other words, it
* helps us manage any process that may generate multiple non-hierarchical errors (an error is not a
* direct consequence of the previous one) by providing us with some tools:
* - Management of the error stack.
* - Simple search for root causes within the error stack.
* - Stack management, both of the current instance of the error, and of the causes.
* - Facilitate error logging.
*
* Furthermore, in combination with the types of error Boom, errors for the REST-API interfaces, and
* Crash, standard application errors, it allows a complete management of the different types of
* errors in our backend.
* @category Multi
* @public
*/
class Multi extends BaseError_1.Base {
constructor(message, uuidOrOptions, options) {
super(message, uuidOrOptions, options);
/** Multi error */
this._isMulti = true;
this._causes = this.extractCauses(this._uuid, this._options);
if (this.name === 'BaseError') {
this.name = 'MultiError';
}
}
/**
* Extract the causes from the options
* @param uuid - unique identifier for this particular occurrence of the problem
* enhanced error options
* @param options - enhanced error options
* @returns
*/
extractCauses(uuid, options) {
if (!(options === null || options === void 0 ? void 0 : options['causes'])) {
return;
}
const causes = options['causes'];
if (!(causes instanceof Crash_1.Crash || causes instanceof Error) && !Array.isArray(causes)) {
throw new BaseError_1.Base('Options[causes] must be an array of Error/Crash', uuid);
}
if (causes instanceof Crash_1.Crash || causes instanceof Error) {
return [causes];
}
for (const cause of causes) {
if (!(cause instanceof Crash_1.Crash || cause instanceof Error)) {
throw new BaseError_1.Base('Options[causes] must be an array of Error/Crash', uuid);
}
}
return causes;
}
/** Determine if this instance is a Multi error */
get isMulti() {
return this._isMulti;
}
/** Causes source of error */
get causes() {
return this._causes;
}
/** Return the number of causes of this error */
get size() {
if (this._causes) {
return this._causes.length;
}
else {
return 0;
}
}
/** Get the trace of this hierarchy of errors */
trace() {
const trace = [];
if (this.causes) {
this.causes.forEach(cause => {
if (cause instanceof Crash_1.Crash) {
trace.push(...cause.trace());
}
else {
trace.push(`${cause.name}: ${cause.message}`);
}
});
}
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 foundCause;
if (this._causes !== undefined) {
this._causes.forEach(cause => {
if (cause.name === name && foundCause === undefined) {
foundCause = cause;
}
if (cause instanceof Crash_1.Crash && foundCause === undefined) {
foundCause = cause.findCauseByName(name);
}
});
}
return foundCause;
}
/**
* 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/Multi was instantiated
*/
fullStack() {
let arrayStack = '';
if (this._causes !== undefined && this._causes.length > 0) {
arrayStack += '\ncaused by ';
this._causes.forEach(cause => {
if (cause instanceof Crash_1.Crash) {
arrayStack += `\n[${cause.fullStack()}]`;
}
else if (cause instanceof Error) {
arrayStack += `\n[${cause.stack}]`;
}
});
}
return this.stack + arrayStack;
}
/**
* Add a new error on the array of causes
* @param error - Cause to be added to the array of causes
*/
push(error) {
if (this._causes !== undefined) {
this._causes.push(error);
}
else {
this._causes = [error];
}
}
/**
* Remove a error from the array of causes
* @returns the cause that have been removed
*/
pop() {
if (this._causes !== undefined) {
return this._causes.pop();
}
else {
return undefined;
}
}
/** Return Multi error in JSON format */
toJSON() {
return {
...super.toObject(),
trace: this.trace(),
};
}
/**
* Process the errors thrown by Joi into the cause array
* @param error - `ValidationError` from a Joi validation process
* @returns number or error that have been introduced
*/
Multify(error) {
if (error.name === 'ValidationError') {
error.details.forEach(detail => {
this.push(new Crash_1.Crash(detail.message, this._uuid, {
name: 'ValidationError',
info: detail,
}));
});
return error.details.length;
}
else {
return 0;
}
}
}
exports.Multi = Multi;
//# sourceMappingURL=MultiError.js.map