| 1 | /** |
| 2 | * helper functions for dealing with the `unknown` type, mainly in `catch` |
| 3 | * blocks or promise rejection callbacks. |
| 4 | * |
| 5 | * @module |
| 6 | */ |
| 7 | |
| 8 | /** extra fields on errors are extremely helpful for debugging. */ |
| 9 | export interface Error extends globalThis.Error { |
| 10 | [metadata: string]: unknown; |
| 11 | } |
| 12 | |
| 13 | /** retrieve an error message from any value */ |
| 14 | export function message(error: unknown): string { |
| 15 | let message = (error as { message: unknown })?.message ?? error; |
| 16 | try { |
| 17 | message = typeof message === "string" |
| 18 | ? message |
| 19 | // NOTE: typescript standard library lies here (https://github.com/mattpocock/ts-reset/pull/190) |
| 20 | : String(JSON.stringify(message) as string | undefined); |
| 21 | } catch {} |
| 22 | try { |
| 23 | return String(message); |
| 24 | } catch {} |
| 25 | return `Could not stringify error message ${typeof message}`; |
| 26 | } |
| 27 | |
| 28 | /** retrieve an error-like object from any value. Useful to check fields. */ |
| 29 | export function obj(error: unknown): { message: string } & Partial<Error> { |
| 30 | if (error instanceof Error) return error as Error; |
| 31 | return { |
| 32 | message: message(error), |
| 33 | ...(typeof error === "object" && error), |
| 34 | }; |
| 35 | } |
| 36 | |
| 37 | /** node.js error codes are string values on the `.code` property. */ |
| 38 | export function code(error: unknown): node.ErrorCode | null { |
| 39 | const code = (error as { code: unknown })?.code; |
| 40 | return typeof code === "string" ? code : null; |
| 41 | } |
| 42 | |
| 43 | /** attach extra fields and rethrow a value. */ |
| 44 | export function rethrowWithMetadata( |
| 45 | err: unknown, |
| 46 | meta: Record<string, unknown>, |
| 47 | ): never { |
| 48 | const error = err && typeof err === "object" ? err : new Error(message(err)); // no stack trace :/ |
| 49 | Object.assign(error, meta); |
| 50 | throw error; |
| 51 | } |
| 52 | |
| 53 | import type * as node from "./node.ts"; |