@dschz/try-catch
Version:
Simple try-catch utility function for JavaScript
134 lines (94 loc) • 3.39 kB
Markdown
[](LICENSE)
[](https://www.npmjs.com/package/@dschz/try-catch)
[](https://bundlephobia.com/package/@dschz/try-catch)
[](https://jsr.io/@dschz/try-catch)
[](https://github.com/dsnchz/try-catch/actions/workflows/ci.yaml)
> A tiny utility to wrap functions or promises and return a `[error, data]` tuple — no more `try/catch` boilerplate.
- Supports synchronous functions, async functions, and direct promises
- Returns the appropriate type based on input — no unnecessary `await` for sync functions
- Strongly typed with exported `Result<T, E>`, `Success<T>`, and `Failure<E>` types
- Non-Error throws are automatically wrapped in an `Error` with `cause`
- Zero dependencies
```bash
npm install @dschz/try-catch
pnpm add @dschz/try-catch
yarn add @dschz/try-catch
bun add @dschz/try-catch
```
Returns `Result<T, E>` directly:
```ts
import { tryCatch } from "@dschz/try-catch";
// Parse JSON
const [err, data] = tryCatch(() => JSON.parse('{"a":1}'));
// Functions that throw
const [err, data] = tryCatch(() => {
throw new RangeError("Out of bounds");
});
// Non-Error throws are wrapped in Error with cause
const [err, data] = tryCatch(() => {
throw "string error";
});
// err.message === "string error", err.cause === "string error"
```
Returns `Promise<Result<T, E>>`:
```ts
const [err, data] = await tryCatch(async () => {
const res = await fetch("/api");
return res.json();
});
```
Returns `Promise<Result<T, E>>`:
```ts
const [err, data] = await tryCatch(fetch("/api/data"));
const [err, data] = await tryCatch(Promise.resolve(42));
const [err, data] = await tryCatch(Promise.reject(new Error("fail")));
```
Returns `Promise<Result<T, E>>`:
```ts
const [err, data] = await tryCatch(() => fetch("/api").then((r) => r.json()));
```
Always wrap expressions that might throw in a function. This ensures the error is caught inside the try-catch scope:
```ts
// CORRECT
tryCatch(() => JSON.parse("{ malformed }"));
// INCORRECT — JSON.parse evaluates and throws before tryCatch is even called
tryCatch(JSON.parse("{ malformed }"));
```
All types are exported for use in your own type definitions:
```ts
import { tryCatch, Result, Success, Failure } from "@dschz/try-catch";
type Success<T> = [error: null, data: T];
type Failure<E extends Error = Error> = [error: E, data: null];
type Result<T, E extends Error = Error> = Success<T> | Failure<E>;
```
The return value is a tuple where one value will always be `null`:
```ts
const [error, data] = tryCatch(() => someOperation());
if (error) {
// handle error
return;
}
// data is available here
```
```ts
class MyError extends Error {
constructor(message: string) {
super(message);
this.name = "MyError";
}
}
const [err, data] = await tryCatch<MyType, MyError>(async () => doSomething());
```
MIT © [Daniel Sanchez](https://github.com/thedanchez)