kequapp
Version:
DEPRECATED: renamed to @kequtech/arbor
87 lines (86 loc) • 2.63 kB
JavaScript
import { STATUS_CODES } from 'node:http';
export const Ex = {
StatusCode,
...errorHelpers(),
};
function StatusCode(statusCode, message, options) {
if (!STATUS_CODES[statusCode]) {
return buildException(StatusCode, 'Error', statusCode, message, options);
}
const key = createMethodName(statusCode);
return buildException(StatusCode, key, statusCode, message, options);
}
function errorHelpers() {
const errorHelpers = {};
const statusCodes = Object.keys(STATUS_CODES).map((statusCode) => parseInt(statusCode, 10));
for (const statusCode of statusCodes) {
if (statusCode < 400)
continue;
const key = createMethodName(statusCode);
errorHelpers[key] = (message, options) => {
return buildException(errorHelpers[key], key, statusCode, message, options);
};
}
return errorHelpers;
}
export function unknownToEx(error) {
if (!(error instanceof Error)) {
const ex = StatusCode(500, createMessage(error));
delete ex.stack;
return ex;
}
const ex = error;
ex.statusCode = ex.statusCode ?? 500;
ex.info = ex.info ?? {};
ex.name = ex.name ?? createMethodName(ex.statusCode);
return ex;
}
function createMessage(message) {
try {
return `[Unknown Problem] ${String(message)}`;
}
catch (_error) {
return '[Unknown Problem]';
}
}
function createMethodName(statusCode) {
return (STATUS_CODES[statusCode] ?? 'Error')
.replace("'", '')
.split(/[\s-]+/)
.map(capitalize)
.join('');
}
function capitalize(word) {
return word.charAt(0).toUpperCase() + word.substring(1);
}
function buildException(parent, name, statusCode, message, options) {
const { cause, ...info } = options ?? {};
const ex = new Error(message ?? STATUS_CODES[statusCode]);
ex.name = name;
ex.statusCode = statusCode;
ex.cause = normalize(cause);
ex.info = normalize(info);
Error.captureStackTrace(ex, parent);
return ex;
}
function normalize(value) {
if (typeof value === 'bigint')
return String(value);
if (typeof value !== 'object' || value === null)
return value;
if (value instanceof Date)
return value;
if (value instanceof Error)
return {
message: value.message,
name: value.name,
cause: normalize(value.cause),
};
if (Array.isArray(value))
return value.map(normalize);
const result = {};
for (const [k, v] of Object.entries(value)) {
result[k] = normalize(v);
}
return result;
}