Skip to content

Error handling

This library distinguishes two kinds of failure. Understanding both keeps your code predictable and type-safe.

Panics

Some methods intentionally panic, mirroring Rust. They throw an internal PanicError synchronously - or, on the async wrappers, reject the returned Promise with one:

MethodPanics when
Result.unwrap()
Option.unwrap()
AsyncResult.unwrap()
AsyncOption.unwrap()
the outcome is Err or None
Result.expect()
Option.expect()
AsyncResult.expect()
AsyncOption.expect()
the outcome is Err or None
Result.unwrapErr()
AsyncResult.unwrapErr()
the value is Ok
Result.expectErr()
AsyncResult.expectErr()
the value is Ok

Use a panic only when reaching an Err or None would mean a bug - for example, after earlier logic has guaranteed success or the presence of a value. When failure or missing data is an expected outcome, handle it explicitly with a non-panicking combinator:

typescript
import { Ok, Err } from 'results-ts';

// recoverable - no panic:
const n = Ok(1).unwrapOr(0); // 1
const m = Err('oops').unwrapOr(0); // 0

// assertion - panics if you are wrong:
const k = Ok(1).unwrap(); // 1
const bad = Err('oops').unwrap(); // throws PanicError

Misuse errors

Almost every method validates its arguments at runtime. If untyped JavaScript or an unsafe type assertion passes a value that violates a method's contract, the method throws a JavaScript error. These errors signal a bug at the call site, not a normal control-flow path.

Error classes are not exported

Internal error classes like PanicError and InvalidArgumentError are intentionally not exported. Thrown errors report broken assumptions or invalid calls; Result and Option are the public APIs for expected failures and absent values.

catchUnwind

Existing or third-party code often throws exceptions or rejects promises. catchUnwind and catchUnwindAsync provide a gentle boundary between that code and a Result pipeline. New code whose failures are expected should usually return Result directly.

catchUnwind wraps a synchronous function and turns a throw into an Err. Its optional onThrow handler can normalize JavaScript's unknown thrown value into a typed error.

typescript
import { catchUnwind } from 'results-ts';

const parseJson = (text: string): unknown => JSON.parse(text);

const safeParse = catchUnwind(parseJson, (thrown) =>
    thrown instanceof Error ? thrown.message : 'parse error'
);

safeParse('{"a":1}'); // Ok({ a: 1 })
safeParse('{bad'); // Err('Unexpected token ...')

Without an onThrow handler, the caught error type remains unknown, because JavaScript allows throwing any value:

typescript
import { catchUnwind } from 'results-ts';

const unsafe = catchUnwind(() => {
    throw 'literal string';
});

const result = unsafe();
//    ^? Result<never, unknown>

catchUnwindAsync captures both synchronous throws and rejected promises and returns an AsyncResult:

typescript
import { catchUnwindAsync } from 'results-ts';

const readJson = async (response: Response): Promise<unknown> =>
    response.json();

const safeFetch = catchUnwindAsync(
    async (url: string) => {
        const response = await fetch(url);
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        return readJson(response);
    },
    (thrown) => (thrown instanceof Error ? thrown.message : 'request failed')
);

const result = await safeFetch('https://api.example.com');
//    ^? Result<unknown, string>

NOTE

The onThrow handler receives the thrown value and the original call arguments: (thrown, ...args) => E.

How this differs from Rust

Rust uses the match keyword syntax; this library provides Result.match() and Option.match() methods to achieve the same branching style in TypeScript. The panic and unwrap semantics, plus the Ok / Err / Some / None naming, follow the Rust originals closely. See the results-ts API reference for this library's behavior and the official Rust docs for Rust's standard library.

Next steps

  • Async guide - use the same pipeline style with asynchronous work.
  • API reference - complete signatures and method documentation.