Skip to content

Commit

Permalink
feat: adds TryCatch
Browse files Browse the repository at this point in the history
  • Loading branch information
OctoD committed Jul 16, 2019
1 parent 7955301 commit 6ee1d54
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 0 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Heavily inspired by rust [std::option](https://doc.rust-lang.org/std/option/inde
- [unwrap](#unwrap-1)
- [unwrapErr](#unwrapErr)
- [unwrapOr](#unwrapOr-1)
- [unwrapOrElse](#unwrapOrElse)
- [TryCatch](#TryCatch)
- [Contributing](#Contributing)
- [Licence](#Licence)

Expand Down Expand Up @@ -376,6 +378,36 @@ Ok('pizza').unwrapOrElse(err => err.message) // 'pizza'
Err('pizza with ananas').unwrapOrElse(err => err.message) // 'pizza with ananas'
```

## TryCatch

These functions handle try/catch.

```ts
import { TryCatch, TryCatchAsync } from 'some.js';

TryCatch(
(a: number, b: number) => a + b,
10,
20,
) // returns Ok(30)

TryCatch(
(a: number, b: number) => a + b + c,
10,
20,
) // returns Err('c is not defined')

TryCatchAsync(
(url: string) => fetch(url).then(r => r.json()),
'https://reqres.in/api/users?page=2'
) // returns Ok({ /* some json data here */ })

TryCatchAsync(
(url: string) => fetch(url).then(r => r.document()),
'https://reqres.in/api/users?page=2'
) // returns Err('r.document is not a function)
```

# Contributing

Read the [contributing guidelines](./CONTRIBUTING.md)
Expand Down
64 changes: 64 additions & 0 deletions src/TryCatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Ok, Err } from "./Result";

export type Fn = () => any;
export type FnAsync = () => Promise<any>;

/**
* Handle sync try/catch.
*
* ```ts
* import { TryCatch, TryCatchAsync } from 'some.js';
*
* TryCatch(
* (a: number, b: number) => a + b,
* 10,
* 20,
* ) // returns Ok(30)
* ```
*
* @export
* @template FnTry
* @template K
* @param {FnTry} fnTry
* @param {...K} args
* @returns {(Ok<ReturnType<FnTry>> | Err)}
*/
export function TryCatch<FnTry extends (...args: K) => any, K extends any[]>(
fnTry: FnTry,
...args: K
): Ok<ReturnType<FnTry>> | Err {
try {
return Ok(fnTry.apply(null, args));
} catch (error) {
return Err(error.message);
}
}

/**
* Handle sync try/catch.
*
* ```ts
* TryCatchAsync(
* (url: string) => fetch(url).then(r => r.json()),
* 'https://reqres.in/api/users?page=2'
* ) // returns Ok({ some json data here })
*
* ```
*
* @export
* @template FnTry
* @template K
* @param {FnTry} fnTry
* @param {...K} args
* @returns {(Promise<Ok<ReturnType<FnTry>> | Err>)}
*/
export async function TryCatchAsync<
FnTry extends (...args: K) => Promise<any>,
K extends any[]
>(fnTry: FnTry, ...args: K): Promise<Ok<ReturnType<FnTry>> | Err> {
try {
return Ok(await fnTry.apply(null, args));
} catch (error) {
return Err(error.message);
}
}
40 changes: 40 additions & 0 deletions src/__tests__/TryCatch.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { TryCatch, TryCatchAsync } from "../TryCatch";
import { Ok, Err } from "../Result";

describe(`TryCatch`, () => {
it("returns the ok fn if does not catch", () => {
expect(TryCatch(() => 10)).toStrictEqual(Ok(10));
});

it("can receive a number N of arguments", () => {
expect(
TryCatch((a: number, b: number) => `received ${a} and ${b}`, 10, 20)
).toStrictEqual(Ok(`received 10 and 20`));
});

it("returns Err if the tryFn catches", () => {
expect(
TryCatch(
// @ts-ignore
() => a + 1
)
).toStrictEqual(Err("a is not defined"));
});

it("handles async functions", async () => {
expect(
await TryCatchAsync(
(a: number, b: number) => Promise.resolve(a + b),
10,
20
)
).toStrictEqual(Ok(30));

expect(
await TryCatchAsync(
// @ts-ignore
() => b * 20
)
).toStrictEqual(Err("b is not defined"));
});
});

0 comments on commit 6ee1d54

Please sign in to comment.