Skip to content

Instantly share code, notes, and snippets.

@wolever
Created November 25, 2019 19:15
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 wolever/f37213c4ca8e876d651d5caaade6ccce to your computer and use it in GitHub Desktop.
Save wolever/f37213c4ca8e876d651d5caaade6ccce to your computer and use it in GitHub Desktop.
/**
* Catches any exception which might be raised by a promise and returns a
* tuple of [result, error], where either the result or the error will be
* undefined:
*
* let [res, error] = await maybe(someApi.get(...))
* if (err) {
* return `Oh no there was an error: ${err}`
* }
* console.log('The result:', res)
*
* The result is also an object with `res` and `err` fields:
*
* let someResult = await maybe(someApi.get(...))
* if (someResult.err) {
* return `Oh no there was an error: ${someResult.err}`
* }
* console.log('The result:', someResult.res)
*
*/
export type MaybeRes<T, E= any> = [T, E] & { res: T, err: E }
export type MaybeFunc<T, E= any> = {
(p: Promise<T>): Promise<MaybeRes<T, E>>
accept: <T, E= any>(res: T) => MaybeRes<T, E>
reject: <E, T= any>(err: E) => MaybeRes<T, E>
unwrap: <T, E= any>(p: Promise<MaybeRes<T, E>>) => Promise<T>
}
export function maybe<T, E= any>(p: Promise<T>): Promise<MaybeRes<T, E>> {
return (p as Promise<T>).then(
res => maybe.accept<T, E>(res),
err => maybe.reject<E, T>(err),
)
}
export namespace maybe {
export const accept = <T, E= any>(res: T): MaybeRes<T, E> => Object.assign([res, null], { res, err: null }) as any
export const reject = <E, T= any>(err: E): MaybeRes<T, E> => Object.assign([null, err], { res: null, err }) as any
export const unwrap = async <T, E>(p: Promise<MaybeRes<T, E>>) => {
const [res, err] = await p
if (err)
throw new Error(err as any)
return res
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment