# Handle a missing title

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

## Useful when

- You want to add Result values to a TypeScript package.
- You need one concrete function and caller to see the full flow.

## What you'll build

A title lookup that returns success or failure, with both branches handled by the caller.

### 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](https://hulla.dev/docs/control/results.md) contains either the title or an error.

## 1. Prepare a project

Create an empty project directory and initialize it:

### Install with bun

```sh
bun init -y
```

### Install with npm

```sh
npm init -y
```

### Install with pnpm

```sh
pnpm init
```

### Install with yarn

```sh
yarn init -y
```

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

### Install with bun

```sh
bun add @hulla/control
```

### Install with npm

```sh
npm install @hulla/control
```

### Install with pnpm

```sh
pnpm add @hulla/control
```

### Install with yarn

```sh
yarn add @hulla/control
```

## 2. Return both possible outcomes

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

```ts filename="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.

## 3. Handle the result

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

```ts filename="src/main.ts"
import { findTitle } from './titles'

const title = findTitle('welcome')

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

## 4. Run both paths

From the project root, run:

```sh
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.

> **Tip: 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](https://hulla.dev/guides/control/config-checker.md) that combines parsing, validation, and a useful CLI error. Read [Results](https://hulla.dev/docs/control/results.md) to compare guards with `match()`.
