Last active
June 14, 2025 01:24
-
Star
(746)
You must be signed in to star a gist -
Fork
(118)
You must be signed in to fork a gist
-
-
Save t3dotgg/a486c4ae66d32bf17c09c73609dacc5b to your computer and use it in GitHub Desktop.
Theo's preferred way of handling try/catch in TypeScript
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 characters
// Types for the result object with discriminated union | |
type Success<T> = { | |
data: T; | |
error: null; | |
}; | |
type Failure<E> = { | |
data: null; | |
error: E; | |
}; | |
type Result<T, E = Error> = Success<T> | Failure<E>; | |
// Main wrapper function | |
export async function tryCatch<T, E = Error>( | |
promise: Promise<T>, | |
): Promise<Result<T, E>> { | |
try { | |
const data = await promise; | |
return { data, error: null }; | |
} catch (error) { | |
return { data: null, error: error as E }; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I used the code above as a baseline and made some adjustments to better suit my needs. I also addressed a few additional edge cases—for example, adding an overload for the never type to prevent the Promise-specific overload from being incorrectly used. Additionally, I handled promises using Promise.resolve to ensure compatibility with external promises. This was particularly helpful in resolving issues I encountered when returning a PrismaPromise without awaiting it first.
Additionally, you could implement support for a second argument—such as a transformError function—to wrap or customize internal errors. This allows for more flexible error handling, especially when you want to add context or standardize error formats.