Skip to content

Commit

Permalink
Merge pull request #3 from jsr-core/add-attempt
Browse files Browse the repository at this point in the history
feat(attempt): add attempt function
  • Loading branch information
lambdalisue authored Aug 21, 2024
2 parents 7b046e7 + 592bc89 commit 8fcde9c
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 0 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@

A utility pack for handling error.

## attempt

`attempt` is a function that executes a function and returns the result
(`[error: unknown, value: T]`). If the function is successful, it returns
`[undefined, value]`. If the function throws an error, it returns
`[error, undefined]`.

```ts
import { assertEquals } from "@std/assert";
import { attempt } from "@core/errorutil/attempt";

assertEquals(attempt(() => 42), [undefined, 42]);
assertEquals(
attempt(() => {
throw "err";
}),
["err", undefined],
);
```

## ErrorObject

`ErrorObject` is a class that wraps an error object for serialization. It is
Expand Down
25 changes: 25 additions & 0 deletions attempt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export type Success<T> = [error: undefined, value: T];
export type Failure<E> = [error: E, value: undefined];
export type Result<T, E> = Success<T> | Failure<E>;

/**
* Attempt to execute a function and return a Result<T, E>.
*
* @param fn - The function to execute.
* @returns A Result<T, E> where T is the return type of the function and E is the error type.
*
* @example
* ```ts
* import { attempt } from "@core/errorutil/attempt";
*
* console.log(attempt(() => 1)); // [undefined, 1]
* console.log(attempt(() => { throw "err" })); // ["err", undefined]
* ```
*/
export function attempt<T, E>(fn: () => T): Result<T, E> {
try {
return [undefined, fn()];
} catch (e) {
return [e, undefined];
}
}
15 changes: 15 additions & 0 deletions attempt_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { test } from "@cross/test";
import { assertEquals } from "@std/assert";
import { attempt } from "./attempt.ts";

test("attempt should return a Success<T> when the function is successful", () => {
const result = attempt(() => 1);
assertEquals(result, [undefined, 1]);
});

test("attempt should return a Failure<E> when the function is failed", () => {
const result = attempt(() => {
throw "err";
});
assertEquals(result, ["err", undefined]);
});
3 changes: 3 additions & 0 deletions deno.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.0.0",
"exports": {
".": "./mod.ts",
"./attempt": "./attempt.ts",
"./error-object": "./error_object.ts",
"./raise": "./raise.ts",
"./try-or": "./try_or.ts",
Expand All @@ -20,12 +21,14 @@
"LICENSE"
],
"exclude": [
"**/*_bench.ts",
"**/*_test.ts",
".*"
]
},
"imports": {
"@core/errorutil": "./mod.ts",
"@core/errorutil/attempt": "./attempt.ts",
"@core/errorutil/error-object": "./error_object.ts",
"@core/errorutil/raise": "./raise.ts",
"@core/errorutil/try-or": "./try_or.ts",
Expand Down
1 change: 1 addition & 0 deletions mod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./attempt.ts";
export * from "./error_object.ts";
export * from "./raise.ts";
export * from "./try_or.ts";
Expand Down

0 comments on commit 8fcde9c

Please sign in to comment.