Skip to content

Instantly share code, notes, and snippets.

@emilien-jegou
Created February 24, 2025 14:31
Show Gist options
  • Save emilien-jegou/82e5bb4f134d4921745bbdc4fcf67b18 to your computer and use it in GitHub Desktop.
Save emilien-jegou/82e5bb4f134d4921745bbdc4fcf67b18 to your computer and use it in GitHub Desktop.
Typescript error handling
import type { Prettify } from 'ts-essentials';
export type Result<T = unknown, E = unknown> = Success<T> | Failure<E>;
export interface Success<T> {
kind: 'success';
value: T;
}
export interface Failure<E> {
kind: 'failure';
error: E;
}
export const success = <T>(value: T): Success<T> => {
return {
kind: 'success',
value: value,
};
};
export const failure = <E>(error: E): Failure<E> => {
return {
kind: 'failure',
error: error,
};
};
// run code in a 'failable' context where thrown exception are converted to a result error
// e.g. failable(() => {throw 'uncaught'; return 123})
export const failable = <const T>(cb: () => T): Result<T, unknown> => {
try {
return success(cb());
} catch (e: unknown) {
return failure<unknown>(e);
}
};
// e.g. failableAsync(() => {throw 'uncaught'; return Promise.resolve(123)})
export const failableAsync = async <const T>(cb: () => Promise<T>): Promise<Result<T, unknown>> => {
try {
return success(await cb());
} catch (e: unknown) {
return failure<unknown>(e);
}
};
// transform a throwable function into a function that return a result type
//
// e.g.:
// const myFunction = (t: boolean): number => {
// if (t) { throw 'invalid' }
// else { return 123 }
// }
// const mySafeFunction = safeify(myFunction)
// mySafeFunction(false) // Success<number>
export const safeify = <const CB extends (...args: any) => any>(
cb: CB,
): ((...args: Parameters<CB>) => Result<Prettify<ReturnType<CB>>, unknown>) => {
return (...args: any) => failable(() => cb(args));
};
export const safeifyAsync = <const Args extends any[], const Ret>(
cb: (...args: Args) => Promise<Ret>,
): ((...args: Args) => Promise<Result<Ret, unknown>>) => {
return (...args: any) => failableAsync(() => cb(...args));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment