@aedart/support
Version:
The Ion support package
138 lines (129 loc) • 4.05 kB
JavaScript
/**
* @aedart/support
*
* BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>.
*/
;
var misc = require('@aedart/support/misc');
var reflections = require('@aedart/support/reflections');
/**
* Captures stack trace and sets stack trace for given error
*
* **Caution**: _Method will mutate given `error` by setting the `stack` property_
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#custom_error_types
*
* @param {Error} error
*
* @return {string|undefined} Captured stack trace
*/
function configureStackTrace(error) {
if (!misc.isset(error)) {
return undefined;
}
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#custom_error_types
if (Reflect.has(Error, 'captureStackTrace') && typeof Error['captureStackTrace'] == 'function') {
Error.captureStackTrace(error, Reflect.getPrototypeOf(error));
}
else {
error.stack = (new Error()).stack;
}
return error.stack;
}
/**
* Configures the custom error
*
* **Note**: _Method sets the custom error's name and optionally captures a [stack trace]{@link configureStackTrace}
* and sets it as the custom error's stack._
*
* **Example**:
* ```
* class MyCustomError extends Error
* {
* constructor(message, options)
* {
* super(message, options)
*
* configureCustomError(this);
* }
* }
* ```
*
* @template T extends Error
*
* @param {Error} error
* @param {boolean} [captureStackTrace=false]
*
* @return {Error}
*/
function configureCustomError(error, captureStackTrace = false) {
if (captureStackTrace) {
configureStackTrace(error);
}
error.name = Reflect.getPrototypeOf(error)?.constructor.name;
return error;
}
/**
* Logical Error
*
* To be thrown whenever there is an error in the programming logic.
*
* This error is inspired by PHP's [`LogicException`]{@link https://www.php.net/manual/en/class.logicexception}
*/
class LogicalError extends Error {
/**
* Create a new logical error instance
*
* @param {string} [message]
* @param {ErrorOptions} [options]
*/
constructor(message, options) {
super(message, options);
configureCustomError(this);
}
}
/**
* Abstract Class Error
*
* To be thrown whenever an abstract class is attempted instantiated directly.
*/
class AbstractClassError extends LogicalError {
/**
* The abstract class that was attempted instantiated
*
* @type {AbstractConstructor}
*/
target;
/**
* Create new instance of Abstract Class Error
*
* @param {AbstractConstructor} target The abstract class that was attempted instantiated directly
* @param {ErrorOptions} [options]
*/
constructor(target, options) {
super(`Unable to create new instance of abstract class ${reflections.getNameOrDesc(target)}`, options || { cause: { target: target } });
configureCustomError(this);
this.target = target;
}
}
/**
* Returns error message from {@link Error}, if possible
*
* @param {any} error Error or value that was thrown
* @param {string} [defaultMessage] A default message to return if unable to resolve error message
*
* @return {string}
*/
function getErrorMessage(error, /* eslint-disable-line @typescript-eslint/no-explicit-any */ defaultMessage = 'unknown reason') {
return (typeof error == 'object' && error instanceof Error && Reflect.has(error, 'message'))
? error.message
: defaultMessage;
}
exports.AbstractClassError = AbstractClassError;
exports.LogicalError = LogicalError;
exports.configureCustomError = configureCustomError;
exports.configureStackTrace = configureStackTrace;
exports.getErrorMessage = getErrorMessage;
module.exports = Object.assign(exports.default, exports);
//# sourceMappingURL=exceptions.cjs.map