Skip to content

Instantly share code, notes, and snippets.

@MCarlomagno
Created August 6, 2022 22:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MCarlomagno/acd0906dbb982a9e6c9455ef45ca86b8 to your computer and use it in GitHub Desktop.
Save MCarlomagno/acd0906dbb982a9e6c9455ef45ca86b8 to your computer and use it in GitHub Desktop.
❌ Go-like error catching implementation to avoid messy try-catch statements in Typescript.
/**
* Go-like error catching implementation.
*
* The 'attempt' function receives a callback function as a parameter
* and calls it inside a try catch statement.
*
* Returns a tuple of [data, error] where 'data' (if exists) is the
* result of the operation and 'error' (if exists)
* is the error from the catch statement.
*/
type AttemptError = {
msg: string;
errorObject: any;
};
type AttemptState<T> = {
result: T | undefined;
error: AttemptError | undefined;
}
type AttemptResult<T> = [T | undefined, AttemptError | undefined];
const attempt = async <T>(
fn: () => Promise<T>
): Promise<AttemptResult<T>> => {
let state: AttemptState<T> = {
result: undefined,
error: undefined,
};
try {
state.result = await fn();
} catch (err) {
state.error = {
msg: 'An error has ocurred',
errorObject: err
};
} finally {
return [state.result, state.error];
}
};
@MCarlomagno
Copy link
Author

Example usage

const riskyFn = async (input: string): string => {
  await someRiskyOperation();
  return 'it works!';
}

const [result, error] = await attempt<string>(() => riskyFn('hope it works'));
if (error) {
 console.error(error.objectError);
 return 'Did not work :(';
}

console.log(result); // 'it works!'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment