Result<T, Fault> everywhere. A Fault carries tag, details, location, metadata and cause, and serialises with toJSON() — built so failures reach Sentry/OTel with where, why and what data. Inspired by neverthrow.
npm add @thourum/faultimport { ok, err, retry, Fault, ServiceError } from '@thourum/fault'
import { safeFetch } from '@thourum/fault/fetch'
import { safeZodParse } from '@thourum/fault/zod'
Fault.onCapture = (f) => Sentry.captureException(f, { extra: f.toJSON() })
const user = await retry(() => safeFetch('https://api.example.com/me'), { times: 3, delayMs: 200 })
.andThen(safeZodParse(userSchema))
.andThen((u) => (u.active ? ok(u) : err(ServiceError('FORBIDDEN', 'inactive'))))
.orInspect((f) => f.capture())| Subpath | Exports |
|---|---|
@thourum/fault |
Result, ResultAsync, ok, err, Fault, ServiceError, retry, … |
@thourum/fault/fetch |
safeFetch |
@thourum/fault/zod |
safeZodParse, fromZodError |
@thourum/fault/drizzle |
safeDb, DatabaseError |
@thourum/fault/pg |
parsePgError |
@thourum/fault/std |
safeJsonParse, safeJsonStringify, safeReadFile, safeWriteFile, safeEnv |
Zero runtime dependencies; zod, drizzle-orm, pg are optional peers. See packages/fault and examples/.
cd packages/fault && bun install && bun run local-ciMIT