-
-
Save Joseph-Martre/3bf5fb08575ab132d82d31a2079f3696 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
/** | |
* Coerces an unknown value into an Error type if it is not an instance of | |
* Error. The original unknown value is still accessible as the cause of the | |
* coerced error. | |
*/ | |
function coerceToError(thrown: unknown) { | |
if (thrown instanceof Error) return thrown; | |
return new Error("COERCED_NON_ERROR_VALUE", { cause: thrown }); | |
} | |
/** | |
* Wraps a Promise-returning operation in a Result tuple to handle errors | |
* without try/catch. | |
*/ | |
export async function tryCatch<T>( | |
promiseCallback: () => Promise<T>, | |
): Promise<[Error, null] | [null, T]> { | |
try { | |
const promise = promiseCallback(); | |
const data = await promise; | |
return [null, data]; | |
} catch (error) { | |
return [coerceToError(error), null]; | |
} | |
} | |
/** | |
* Wraps a synchronous operation in a Result tuple to handle errors without | |
* try/catch. | |
*/ | |
export function tryCatchSync<T>(callback: () => T): [Error, null] | [null, T] { | |
try { | |
const data = callback(); | |
return [null, data]; | |
} catch (error) { | |
return [coerceToError(error), null]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Summary of the changes:
-Added an error-coercion util function to handle thrown non-error values gracefully.
-Changed the returned object into a tuple to make the naming of destructured variables simpler, and to discourage ignoring errors by not accessing them in the returned object.
-Put the error in the first position of the tuple to discourage not handling errors.
-Modified the return types to make the structure of the returned tuple explicit.
-Added a synchronous version of the function, based on deferred evaluation of a callback instead of a promise.
-Modified the async version to use a callback function as a parameter so that errors thrown before the promise is returned are caught as well.