Skip to content

Instantly share code, notes, and snippets.

@HektorW
Last active February 3, 2025 10:27
Show Gist options
  • Save HektorW/e2b0b611edb760a3ac3ac83375741d87 to your computer and use it in GitHub Desktop.
Save HektorW/e2b0b611edb760a3ac3ac83375741d87 to your computer and use it in GitHub Desktop.
// Inspired from a package I think is called ts-attempt but can't find it anymore.
const failSymbol = Symbol('fail')
type Ok<T> = T
type Fail = { [failSymbol]: true; error: unknown }
type Result<T> = Ok<T> | Fail
export async function attempt<T>(fn: () => Promise<T>): Promise<Result<T>> {
try {
return await fn()
} catch (error) {
return { [failSymbol]: true, error }
}
}
export function isFail<T>(result: Result<T>): result is Fail {
return typeof result === 'object' && result !== null && failSymbol in result
}
export function isOk<T>(result: Result<T>): result is Ok<T> {
return !isFail(result)
}
// ----------
// https://www.npmjs.com/package/tuple-it
// Pretty much copied from ☝️ with minor change and name changes
type TryCatchResult<T> = [TryCatchError] | [null, T]
export async function trycatch<T = unknown>(
maybePromise: Promise<T> | PromiseLike<T> | T
): Promise<TryCatchResult<T>> {
try {
return [null, await maybePromise]
} catch (error) {
return [new TryCatchError(error)]
}
}
export class TryCatchError<E = unknown> extends Error {
error: E
constructor(error: E) {
const message =
error instanceof Error
? error.message
: 'Promise rejected with a non instance of Error'
super(message)
this.error = error
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment