Last active
January 7, 2025 16:06
-
-
Save manzt/3702f19abb714e21c22ce48851c75abf to your computer and use it in GitHub Desktop.
Revisions
-
manzt revised this gist
Jan 7, 2025 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ // Copyright (c) 2024 Trevor Manz - MIT License /** * Type-safe error handling utilities inspired by Python's try/except. * -
manzt created this gist
Jan 7, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,72 @@ /** * Type-safe error handling utilities inspired by Python's try/except. * * @module */ // deno-lint-ignore no-explicit-any type InstanceType<T> = T extends new (...args: any[]) => infer R ? R : never; // deno-lint-ignore no-explicit-any type UnionInstanceType<T extends readonly (new (...args: any[]) => any)[]> = InstanceType<T[number]>; /** * Ensures an error matches expected type(s), otherwise rethrows. * * Unmatched errors bubble up, like Python's `except`. Narrows error types for * type-safe property access. * * @example Catch specific error * ```ts * class NotFoundError extends Error { * getStatus() { return 404 } * } * * try { * // This will bubble up since it's not a NotFoundError * throw new Error("Unexpected error"); * } catch (err) { * except(err, NotFoundError); * // Only NotFoundError reaches here * err.getStatus(); * } * ``` * * @example Handle multiple error types * ```ts * class DbError extends Error { * query: string; * } * class NetworkError extends Error { * code: number; * } * * try { * await db.query(); * } catch (err) { * except(err, DbError, NetworkError); * // Only DbError or NetworkError reach here * if (err instanceof DbError) { * console.log(err.query); * } else { * console.log(err.code); * } * } * ``` * * @param error - The error to check * @param errorClasses - Expected error type(s) * @throws The original error if it doesn't match expected type(s) */ export function except< // deno-lint-ignore no-explicit-any ErrorClasses extends readonly (new (...args: any[]) => Error)[], >( error: unknown, ...errorClasses: ErrorClasses ): asserts error is UnionInstanceType<ErrorClasses> { if (!errorClasses.some((ErrorClass) => error instanceof ErrorClass)) { throw error; } }