Guide

Handle a missing title

Return a title or an error and handle both in the caller.

On this page

Before you start

  • Bun and a directory for a small TypeScript project.

You’ll build a title lookup and a caller that handles a missing title. The return type makes both outcomes visible: a Result contains either the title or an error.

Create an empty project directory and initialize it:

Install @hulla/control in the TypeScript package that will define and call the function:

Create src/titles.ts. The function returns ok() with a title it finds, or err() with a message for a missing title:

src/titles.ts
import { err, ok, type Result } from '@hulla/control'

export function findTitle(id: string): Result<string, Error> {
  if (id === 'welcome') {
    return ok('Welcome')
  }

  return err(new Error(`No title for ${id}`))
}

findTitle('welcome') returns Ok('Welcome'). Any other ID returns Err. Next, let the caller handle both.

Create src/main.ts to call the function. Check isErr() before reading .error; in the other branch, .value contains the title.

src/main.ts
import { findTitle } from './titles'

const title = findTitle('welcome')

if (title.isErr()) {
  console.error(title.error.message)
} else {
  console.log(title.value)
}

From the project root, run:

Terminal
bun src/main.ts
# Welcome

Change findTitle('welcome') to findTitle('missing') and run it again. It prints No title for missing. Both outcomes reach the caller without throwing.

Narrow before reading

.value belongs to the success branch and .error belongs to the failure branch. The type guard tells TypeScript which one you have. unwrap() returns either payload; it doesn’t throw an error for you.

Next, build a config checker that combines parsing, validation, and a useful CLI error. Read Results to compare guards with match().