diff --git a/README.md b/README.md index 0eaedf7..e5ba441 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/attempt.ts b/attempt.ts new file mode 100644 index 0000000..56fc3ea --- /dev/null +++ b/attempt.ts @@ -0,0 +1,25 @@ +export type Success = [error: undefined, value: T]; +export type Failure = [error: E, value: undefined]; +export type Result = Success | Failure; + +/** + * Attempt to execute a function and return a Result. + * + * @param fn - The function to execute. + * @returns A Result 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(fn: () => T): Result { + try { + return [undefined, fn()]; + } catch (e) { + return [e, undefined]; + } +} diff --git a/attempt_test.ts b/attempt_test.ts new file mode 100644 index 0000000..7332afb --- /dev/null +++ b/attempt_test.ts @@ -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 when the function is successful", () => { + const result = attempt(() => 1); + assertEquals(result, [undefined, 1]); +}); + +test("attempt should return a Failure when the function is failed", () => { + const result = attempt(() => { + throw "err"; + }); + assertEquals(result, ["err", undefined]); +}); diff --git a/deno.jsonc b/deno.jsonc index 27fab66..2acedf8 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -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", @@ -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", diff --git a/mod.ts b/mod.ts index ef4c1a0..3eed553 100644 --- a/mod.ts +++ b/mod.ts @@ -1,3 +1,4 @@ +export * from "./attempt.ts"; export * from "./error_object.ts"; export * from "./raise.ts"; export * from "./try_or.ts";