UNPKG

@jchip/error

Version:

utilities and polyfill for node.js errors

117 lines 4.11 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AggregateError = exports.aggregateErrorStack = exports.aggregateStack = exports.cleanErrorStack = void 0; const path_1 = __importDefault(require("path")); /* eslint-disable @typescript-eslint/ban-ts-comment */ const defaultPathFilter = [ new RegExp(`/node_modules.*/(pirates/|isomorphic-loader/lib/extend-require)`), ]; /** * Return the stack text of an error with internal modules removed * * @param error - error * @param options - clean error stack options * @returns cleaned up stack trace */ function cleanErrorStack(error, { replacePath = `${process.cwd()}/`, ignorePathFilter = [] } = {}) { const stack = error && (error.stack || error.message); if (!stack) { return String(stack); } const result = stack .split("\n") .map((line) => { // keep all non stack tracing lines if (!line.match(/ {4,}at/)) { return line; } const match = line.match(/( {4,}at)([^\(]+\()([^\)]+\))(.*)/); // skip any stack tracing line not in these formats: // - " at Blah (/foo/bar:##:##)" format // - "scheme://path" (ie: webpack://path) if (!match || (!match[3].match(/[^:]+:\/\//) && !path_1.default.isAbsolute(match[3]))) { return false; } const path = match[3].replace(/\\/g, "/"); if (defaultPathFilter .concat(ignorePathFilter) .find((s) => s && (s instanceof RegExp ? path.match(s) : path.includes(s)))) { return false; } const path2 = replacePath && replacePath.length > 1 ? path.replace(replacePath, "") : path; return `${match[1]}${match[2]}${path2}${match[4]}`; }) .filter((x) => x) .join("\n"); return result; } exports.cleanErrorStack = cleanErrorStack; /** * Build stack of aggregate errors * * @param stack - top error * @param errors - aggregated errors * @returns aggregate stack */ function aggregateStack(stack, errors) { return [stack] .concat(errors && errors.map && errors.map((e) => { const s = e && (e.stack || e.message); return (s || String(e)).replace(/^/gm, " "); })) .join("\n"); } exports.aggregateStack = aggregateStack; /** * build the aggregate stack of an AggregateError * * @param error aggregate error * @returns aggregate stack */ /* eslint-disable-next-line no-use-before-define */ function aggregateErrorStack(error) { return aggregateStack(error.__stack || error.message || String(error), error.errors); } exports.aggregateErrorStack = aggregateErrorStack; /** * AggregateError * - https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-aggregate-error-objects */ class AggregateError extends Error { constructor(errors, msg) { if (!errors || !(errors[Symbol.iterator] instanceof Function)) { throw new TypeError(`input errors must be iterable but it's ${typeof errors}`); } super(msg); // Using defineProperty to replicate behavior of Object.keys(new Error()) returns [] Object.defineProperty(this, "name", { value: "AggregateError" }); let aggStack; Object.defineProperties(this, { // specify errors according to spec errors: { configurable: true, enumerable: false, writable: true, value: [].concat(errors), }, // save original stack __stack: { enumerable: false, value: this.stack, }, // make aggregate stack stack: { get() { return aggStack || (aggStack = aggregateErrorStack(this)); }, }, }); } } exports.AggregateError = AggregateError; //# sourceMappingURL=index.js.map