UNPKG

@aedart/support

Version:

The Ion support package

131 lines (122 loc) 3.8 kB
import { isset } from '@aedart/support/misc'; import { getNameOrDesc } from '@aedart/support/reflections'; /** * @aedart/support * * BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>. */ /** * 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 (!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 ${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; } export { AbstractClassError, LogicalError, configureCustomError, configureStackTrace, getErrorMessage };