UNPKG

@visulima/error

Version:

Error with more than just a message, stacktrace parsing.

143 lines (139 loc) 3.74 kB
import { i as isPlainObject } from './index-y_UPkY2Z.js'; const ErrorProto = Object.create( {}, { cause: { enumerable: true, value: void 0, writable: true }, code: { enumerable: true, value: void 0, writable: true }, errors: { enumerable: true, value: void 0, writable: true }, message: { enumerable: true, value: void 0, writable: true }, name: { enumerable: true, value: void 0, writable: true }, stack: { enumerable: true, value: void 0, writable: true } } ); const toJsonWasCalled = /* @__PURE__ */ new WeakSet(); const toJSON = (from) => { toJsonWasCalled.add(from); const json = from.toJSON(); toJsonWasCalled.delete(from); return json; }; const serializeValue = (value, seen, depth, options) => { if (value && value instanceof Uint8Array && value.constructor.name === "Buffer") { return "[object Buffer]"; } if (value !== null && typeof value === "object" && typeof value.pipe === "function") { return "[object Stream]"; } if (value instanceof Error) { if (seen.includes(value)) { return "[Circular]"; } depth += 1; return _serialize(value, options, seen, depth); } if (options.useToJSON && typeof value.toJSON === "function") { return value.toJSON(); } if (typeof value === "object" && value instanceof Date) { return value.toISOString(); } if (typeof value === "function") { return `[Function: ${value.name || "anonymous"}]`; } if (isPlainObject(value)) { depth += 1; if (options.maxDepth && depth >= options.maxDepth) { return {}; } const plainObject = {}; for (const key in value) { plainObject[key] = serializeValue(value[key], seen, depth, options); } return plainObject; } try { return value; } catch { return "[Not Available]"; } }; const _serialize = (error, options, seen, depth) => { seen.push(error); if (options.maxDepth === 0) { return {}; } if (options.useToJSON && typeof error.toJSON === "function" && !toJsonWasCalled.has(error)) { return toJSON(error); } const protoError = Object.create(ErrorProto); protoError.name = Object.prototype.toString.call(error.constructor) === "[object Function]" ? error.constructor.name : error.name; protoError.message = error.message; protoError.stack = error.stack; if (Array.isArray(error.errors)) { const aggregateErrors = []; for (const aggregateError of error.errors) { if (!(aggregateError instanceof Error)) { throw new TypeError("All errors in the 'errors' property must be instances of Error"); } if (seen.includes(aggregateError)) { protoError.errors = []; return protoError; } aggregateErrors.push(_serialize(aggregateError, options, seen, depth)); } protoError.errors = aggregateErrors; } if (error.cause instanceof Error && !seen.includes(error.cause)) { protoError.cause = _serialize(error.cause, options, seen, depth); } for (const key in error) { if (protoError[key] === void 0) { const value = error[key]; protoError[key] = serializeValue(value, seen, depth, options); } } if (Array.isArray(options.exclude) && options.exclude.length > 0) { for (const key of options.exclude) { try { delete protoError[key]; } catch { } } } return protoError; }; const serialize = (error, options = {}) => _serialize( error, { exclude: options.exclude ?? [], maxDepth: options.maxDepth ?? Number.POSITIVE_INFINITY, useToJSON: options.useToJSON ?? false }, [], 0 ); export { serialize };