Skip to content

Instantly share code, notes, and snippets.

@brunoti
Created August 14, 2022 21:53
Show Gist options
  • Save brunoti/889df7fc973ae737e8cf24f98c567583 to your computer and use it in GitHub Desktop.
Save brunoti/889df7fc973ae737e8cf24f98c567583 to your computer and use it in GitHub Desktop.
Ramda tryCatch in pure TS
type AnyFunction = (...args: any[]) => any
/**
* `R.tryCatch` takes two functions, a `tryer` and a `catcher`.
* The returned function evaluates the `tryer`;
* if it does not throw, it simply returns the result.
* If the `tryer` does throw,
* the returned function evaluates the `catcher` function and returns its result.
*
* @note For effective composition with this function,
* both the `tryer` and `catcher` functions must return the same type of results.
*
* @example
* ```typescript
* R.tryCatch(R.prop('x'), R.F)({ x: true }); //=> true
* R.tryCatch((_s: string) => { throw 'foo' }, R.always('caught'))('bar') //=> 'caught'
* // Don't do this, it's just an example
* R.tryCatch(R.times(R.identity), R.always([]))('s' as never) //=> []
* R.tryCatch((_s: string) => { throw 'this is not a valid value' }, (err, value)=>({ error: err, value }))('bar')
* //=> {'error': 'this is not a valid value', 'value': 'bar'}
* ```
*/
export function tryCatch<
Tryer extends AnyFunction,
RE = ReturnType<Tryer>,
E = unknown,
>(
tryer: Tryer,
catcher: (error: E, ...args: Parameters<Tryer>) => RE,
): (...args: Parameters<Tryer>) => RE
export function tryCatch<Tryer extends AnyFunction>(
tryer: Tryer,
): <RE = ReturnType<Tryer>, E = unknown>(
catcher: (error: E, ...args: Parameters<Tryer>) => RE,
) => (...args: Parameters<Tryer>) => RE
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export function tryCatch<
Tryer extends AnyFunction,
RE = ReturnType<Tryer>,
E = unknown,
>(tryer: Tryer, catcher?: (error: E, ...args: Parameters<Tryer>) => RE) {
if (catcher === undefined) {
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
return function result(
cCatcher: (error: E, ...args: Parameters<Tryer>) => RE,
) {
return tryCatch<Tryer, RE, E>(tryer, cCatcher)
}
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
return function result(...args: Parameters<Tryer>) {
try {
return tryer(...args)
} catch (error) {
return catcher(error, ...args)
}
}
}
@brunoti
Copy link
Author

brunoti commented Nov 21, 2023

Cut duration of animated GIF

@brunoti
Copy link
Author

brunoti commented Nov 21, 2023

CleanShot 2023-11-21 at 10 56 52

@brunoti
Copy link
Author

brunoti commented Nov 21, 2023

CleanShot 2023-11-21 at 16 48 09

@brunoti
Copy link
Author

brunoti commented Nov 21, 2023

CleanShot 2023-11-21 at 16 53 27

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