@tapjs/error-serdes
Version:
Port of node's error_serdes.js to userland, plus test message streaming
99 lines • 3.49 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.serializeError = void 0;
// This module is more or less a direct port of the serialization logic
// from node's lib/internal/error_serdes module, with primordials removed.
const constants_js_1 = require("./constants.js");
const node_util_1 = require("node:util");
const v8_1 = require("v8");
const getAllProps = (obj, target = obj) => {
const all = Object.create(null);
if (obj === null)
return all;
Object.assign(all, getAllProps(Object.getPrototypeOf(obj), target));
const keys = Object.getOwnPropertyNames(obj);
for (const key of keys) {
const desc = Object.getOwnPropertyDescriptor(obj, key);
/* c8 ignore start */
if (!desc)
continue;
/* c8 ignore stop */
const getter = desc.get;
if (getter) {
try {
delete desc.get;
delete desc.set;
desc.value = getter.call(target);
}
catch { }
}
if (key === 'cause') {
desc.value = (0, exports.serializeError)(desc.value);
all.cause = desc;
}
else if ('value' in desc &&
typeof desc.value !== 'function' &&
typeof desc.value !== 'symbol') {
all[key] = desc;
}
}
return all;
};
const isError = (obj) => typeof obj === 'object' &&
Object.prototype.toString.call(obj) === '[object Error]';
const getCtors = (obj) => {
const ctors = [];
for (let cur = obj; cur !== null; cur = Object.getPrototypeOf(cur)) {
const desc = Object.getOwnPropertyDescriptor(cur, 'constructor');
const value = desc?.value;
if (typeof value === 'function') {
ctors.push(value);
}
}
return ctors;
};
const getName = (f) => {
const n = Object.getOwnPropertyDescriptor(f, 'name')?.value;
if (typeof n === 'string')
return n;
};
const serializeError = (er) => {
if (typeof er === 'symbol') {
return Buffer.from(String.fromCharCode(constants_js_1.kInspectedSymbol) + String(er), 'utf8');
}
try {
if (isError(er)) {
const ctors = getCtors(er);
for (const c of ctors) {
const name = getName(c);
if (name && constants_js_1.errorCtorNames.has(name)) {
const serialized = (0, v8_1.serialize)({
constructor: name,
properties: getAllProps(er),
});
return Buffer.concat([
Buffer.from([constants_js_1.kSerializedError]),
serialized,
]);
}
}
/* c8 ignore start */
}
}
catch { }
/* c8 ignore stop */
try {
if (er !== null && er !== undefined && constants_js_1.kCustomInspect in er) {
return Buffer.from(String.fromCharCode(constants_js_1.kCustomInspectedObject) + (0, node_util_1.inspect)(er), 'utf8');
}
}
catch { }
try {
const serialized = (0, v8_1.serialize)(er);
return Buffer.concat([Buffer.from([constants_js_1.kSerializedObject]), serialized]);
}
catch { }
return Buffer.from(String.fromCharCode(constants_js_1.kInspectedError) + (0, node_util_1.inspect)(er), 'utf8');
};
exports.serializeError = serializeError;
//# sourceMappingURL=serialize.js.map