"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fast_safe_stringify_1 = __importDefault(require("fast-safe-stringify")); class BaseError extends Error { constructor(message, data) { super(message); this.name = this.constructor.name; const err = Object.create(this, { stack: { get() { const originalStack = Object.getPrototypeOf(this).stack || ''; return this.getStack(originalStack); }, set(val) { this.cachedStack = val; }, }, cachedStack: { configurable: true, enumerable: false, value: null, writable: true, }, source: { configurable: true, enumerable: false, value: null, writable: true, }, }); if (data) Object.assign(err, data); return err; } static create(message, data) { return new BaseError(message, data); } static wrap(source, message, data) { const Class = this.prototype.constructor; // @ts-ignore return new Class(message, data).wrap(source, /*passedCachedStack*/ data ? 'cachedStack' in data : false); } static wrapAndThrow(source, message, data) { throw this.wrap(source, message, data); } static assert(condition, message, data) { const Class = this.prototype.constructor; if (!condition) { // @ts-ignore const err = new Class(message, { ...data, condition }); err.stack = err.stack.replace(/[ ]+at .*\n/, ''); throw err; } } getStack(originalStack) { if (this.cachedStack) return this.cachedStack; let cached = false; let stack = originalStack; const { message: _, name: __, ...data } = this; if (hasKey(data)) { // hacks for better stringification // @ts-ignore: better regexp stringification RegExp.prototype.toJSON = // @ts-ignore: better regexp stringification RegExp.prototype.toJSON || RegExp.prototype.toString; stack += '\n' + fast_safe_stringify_1.default(data, undefined, 2); this.cachedStack = stack; cached = true; // remove hacks for stringification // @ts-ignore: remove hack delete RegExp.prototype.toJSON; } if (this.source) { stack += '\n----\n' + (this.source.stack || this.source.message); this.cachedStack = stack; cached = true; } if (cached) this.cachedStack += '\n'; return this.cachedStack || stack; } wrap(source, passedCachedStack) { // @ts-ignore this.source = source; if (!passedCachedStack) { this.cachedStack = null; } return this; } } exports.default = BaseError; function hasKey(obj) { for (const key in obj) { return true; } return false; } //# sourceMappingURL=index.js.map