sitegen/framework/lib/error.ts

48 lines
1.4 KiB
TypeScript
Raw Normal View History

2025-08-14 20:35:33 -07:00
declare global {
interface Error {
/* Extra fields on errors are extremely helpful for debugging. */
[metadata: string]: unknown;
}
}
/** Retrieve an error message from any value */
export function message(error: unknown): string {
const message = (error as { message: unknown })?.message ?? error;
try {
return typeof message === "string" ? message : JSON.stringify(message);
} catch {}
try {
return String(message);
} catch {}
return `Could not stringify error message ${typeof message}`;
}
/** Retrieve an error-like object from any value. Useful to check fields. */
export function obj(error: unknown): { message: string } & Partial<Error> {
if (error instanceof Error) return error;
return {
message: message(error),
...(typeof error === "object" && error),
};
}
/* Node.js error codes are strings */
export function code(error: unknown): NodeErrorCode | null {
const code = (error as { code: unknown })?.code;
return typeof code === "string" ? code : null;
}
/** Attach extra fields and throw */
export function rethrowWithMetadata(
err: unknown,
meta: Record<string, unknown>,
): never {
const error = err && typeof err === "object" ? err : new Error(message(err)); // no stack trace :/
Object.assign(error, meta);
throw error;
}
export type NodeErrorCode =
| keyof typeof import("node:os").constants.errno
| (string & {});