@visulima/error
Version:
Error with more than just a message, stacktrace parsing.
143 lines (139 loc) • 3.74 kB
JavaScript
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 };