doba

Result

Functional error handling with discriminated unions

doba uses a functional approach to error handling. Instead of throwing exceptions, operations return a Result type.

Result types

ResultOk

A successful result with a typed value and metadata:

type ResultOk<T, M = unknown> = {
  readonly ok: true
  readonly value: T
  readonly meta: M
}
ok: true
value: { id: "user-123", email: "alice@example.com" }
meta: {
path: ["database", "frontend"]
steps: 1
warnings: []
}

ResultErr

A failed result with typed issues:

type ResultErr<E = unknown> = {
  readonly ok: false
  readonly issues: E
}
ok: false
issues:
- Expected string, received number at "id"
- Invalid email format at "email"

DobaIssue

All issues returned by doba use this shape:

type DobaIssue = {
  readonly code: DobaIssueCode
  readonly message: string
  readonly path?: readonly PropertyKey[]
  readonly meta?: Record<string, unknown>
}

type DobaIssueCode =
  | 'validation_failed'
  | 'transform_failed'
  | 'no_path_found'
  | 'unknown_schema'
  | 'invalid_input'

Constructors

ok()

Creates a successful result:

import { ok } from 'dobajs/result'

const result = ok(value, meta)

err()

Creates a failed result:

import { err } from 'dobajs/result'

const result = err(issues)

Type guards

isOk() / isErr()

Narrow the result type:

import { isOk, isErr } from 'dobajs/result'

if (isOk(result)) {
  console.log(result.value)
}

if (isErr(result)) {
  console.error(result.issues)
}

Utilities

unwrap()

Extracts the value or throws if it's an error. Use when you're certain the operation succeeded.

import { unwrap } from 'dobajs/result'

const data = unwrap(result)

unwrapOr()

Extracts the value or returns a default fallback:

import { unwrapOr } from 'dobajs/result'

const data = unwrapOr(result, fallbackValue)

map()

Transforms the value if successful, passes errors through unchanged:

import { map } from 'dobajs/result'

const email = map(result, (user) => user.email)

mapErr()

Transforms the issues if failed, passes successes through unchanged:

import { mapErr } from 'dobajs/result'

const formatted = mapErr(result, (issues) => issues.map((i) => i.message))

On this page