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 { 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, ): 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 & {});