A fun way to "try-catch" Typescript errors without interrupting normal user flow
Experiment with a playful "try-catch" approach to Typescript errors while maintaining user flow.
![A fun way to "try-catch" Typescript errors without interrupting normal user flow](/content/images/size/w1200/2024/04/A-fun-way-to-try-catch-Typescript-errors.png)
Code Snippet
type Func<T extends any[], R> = (...args: T) => Promise<R>;
const tryToCatch = async <T extends any[], R, E = unknown>(
fn: Func<T, R>,
...args: T
): Promise<[E | unknown, R | undefined]> => {
try {
const result = await fn(...args);
return [null, result];
} catch (err) {
return [err, undefined];
}
};
Func<T extends any[], R>
is a type alias for a function that takes arguments of typeT
and returns aPromise
of typeR
.- The
tryToCatch
function takes a generic functionfn
of typeFunc<T, R>
and its argumentsargs
of typeT
. - The return type of
tryToCatch
is explicitly defined asPromise<[Error | null, R | undefined]>
, indicating that it returns a promise that resolves to a tuple containing an error (ornull
) and the result of the function (orundefined
if an error occurred). - Inside the function, the
await
keyword is used to handle the asynchronous execution offn
. - The
error
andresult
variables are type-inferred based on the generic types provided to thetryToCatch
function. - When an error occurs, it can now be of type
E
orunknown
. - You can specify the type of error you expect by providing a type argument when calling
tryToCatch
. If you don't specify a type, the error will default tounknown
. - When accessing properties of the error (like
message
), you may need to use a type assertion (e.g.,(error as Error).message
) or type guards to ensure type safety.
Example of Usage
const asyncFunction = async (x: number, y: number): Promise<number> => {
if (y === 0) {
throw new Error("Division by zero");
}
return x / y;
};
const [error, result] = await tryToCatch(asyncFunction, 10, 5);
if (error) {
console.error("Error occurred:", (error as Error).message);
} else {
console.log("Result:", result); // Output: Result: 2
}