45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
export function extractErrorCode(err: unknown): string | undefined {
|
|
if (!err || typeof err !== "object") return undefined;
|
|
const code = (err as { code?: unknown }).code;
|
|
if (typeof code === "string") return code;
|
|
if (typeof code === "number") return String(code);
|
|
return undefined;
|
|
}
|
|
|
|
export function formatErrorMessage(err: unknown): string {
|
|
if (err instanceof Error) {
|
|
return err.message || err.name || "Error";
|
|
}
|
|
if (typeof err === "string") return err;
|
|
if (typeof err === "number" || typeof err === "boolean" || typeof err === "bigint") {
|
|
return String(err);
|
|
}
|
|
try {
|
|
return JSON.stringify(err);
|
|
} catch {
|
|
return Object.prototype.toString.call(err);
|
|
}
|
|
}
|
|
|
|
/** Extract diagnostic detail from a network error's cause chain (e.g. APIConnectionError). */
|
|
export function describeNetworkError(err: unknown): string {
|
|
const msg = formatErrorMessage(err);
|
|
const cause = (err as { cause?: unknown })?.cause;
|
|
if (!cause) return msg;
|
|
const code = extractErrorCode(cause);
|
|
const causeMsg = cause instanceof Error ? cause.message : undefined;
|
|
const detail = code ?? causeMsg;
|
|
if (!detail || msg.includes(detail)) return msg;
|
|
return `${msg} (${detail})`;
|
|
}
|
|
|
|
export function formatUncaughtError(err: unknown): string {
|
|
if (extractErrorCode(err) === "INVALID_CONFIG") {
|
|
return formatErrorMessage(err);
|
|
}
|
|
if (err instanceof Error) {
|
|
return err.stack ?? err.message ?? err.name;
|
|
}
|
|
return formatErrorMessage(err);
|
|
}
|