> ## Documentation Index
> Fetch the complete documentation index at: https://forst-lang.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Return a named error

> Give each expected failure a name and fields the caller can use.

Use a **named error** for an expected failure that your application can handle.
Examples include missing stock, invalid input, and a declined payment. Each
failure gets a stable name. Callers can respond to the error without parsing
its message.

## Declare a failure

Declare each kind of failure with the **`error`** keyword. Add fields when the caller needs
details about what went wrong.

<Tabs>
  <Tab title="Forst">
    ```ft theme={"theme":{"light":"github-light-default","dark":"dark-plus"}}
    error UnknownStockKeepingUnit {}

    error InsufficientStock {
    	stockKeepingUnit: String,
    	requested:        Int,
    	available:        Int,
    }
    ```
  </Tab>

  <Tab title="Generated Go">
    ```go theme={"theme":{"light":"github-light-default","dark":"dark-plus"}}
    // forst build
    type UnknownStockKeepingUnit struct{}

    func (e UnknownStockKeepingUnit) Error() string {
    	return "UnknownStockKeepingUnit"
    }

    type InsufficientStock struct {
    	stockKeepingUnit string
    	requested        int
    	available        int
    }

    func (e InsufficientStock) Error() string { /* ... */ }
    ```
  </Tab>
</Tabs>

These two errors remain different types even if their fields later become the
same. The generated Go types implement the standard `error` interface.

## Return it from a check

Use `ensure … else ErrorName{…}` when a failed check should return a known
error. The function stops at that point and gives the error to its caller.

Here `in` is the order request and `catalog` maps SKUs to quantities:

<Tabs>
  <Tab title="Forst">
    ```ft theme={"theme":{"light":"github-light-default","dark":"dark-plus"}}
    avail := catalog[in.stockKeepingUnit]
    ensure avail
    ensure in.quantity is Max(avail) else InsufficientStock{
    	stockKeepingUnit: in.stockKeepingUnit,
    	requested:        in.quantity,
    	available:        avail,
    }
    ```
  </Tab>

  <Tab title="Generated Go">
    ```go theme={"theme":{"light":"github-light-default","dark":"dark-plus"}}
    // forst build
    import "errors"

    var errMissingMapKey = errors.New("missing map key")

    avail, availErr := func() (int, error) {
    	v, ok := catalog[in.stockKeepingUnit]
    	if !ok {
    		return 0, errMissingMapKey
    	}
    	return v, nil
    }()
    if availErr != nil {
    	return availErr
    }
    if in.quantity > avail {
    	return InsufficientStock{
    		stockKeepingUnit: in.stockKeepingUnit,
    		requested:        in.quantity,
    		available:        avail,
    	}
    }
    ```
  </Tab>
</Tabs>

The first check requires `avail` to contain a successful value. The second
check returns `InsufficientStock` with details that the caller can use. See
[Check a value](/docs/language/check-a-value) for how `ensure` works.

## Start with an empty error

An error can carry no fields when the name alone is enough:

<Tabs>
  <Tab title="Forst">
    ```ft theme={"theme":{"light":"github-light-default","dark":"dark-plus"}}
    error EmptyName {}

    func greet(name String) {
    	ensure name is Min(1) else EmptyName{}
    	return "hello, " + name
    }
    ```
  </Tab>

  <Tab title="Generated Go">
    ```go theme={"theme":{"light":"github-light-default","dark":"dark-plus"}}
    // forst build
    import utf8 "unicode/utf8"

    type EmptyName struct{}

    func (e EmptyName) Error() string { return "EmptyName" }

    func (e EmptyName) ForstErrorTag() string {
    	return "main/EmptyName"
    }

    func greet(name string) (string, error) {
    	if utf8.RuneCountInString(name) < 1 {
    		return "", EmptyName{}
    	}
    	return "hello, " + name, nil
    }
    ```
  </Tab>
</Tabs>

`EmptyName` has no fields. The caller only needs to know that the name was
empty.

## What generated Go looks like

In Go, you usually declare a struct and add an `Error()` method. Forst's
`error Name { … }` declaration creates both parts from one declaration. The
generated result remains an ordinary Go error.

## Functions that can fail

A function that can return these errors becomes a **`Result`**. The caller checks
success before using the value. See
[Functions that can fail](/docs/language/result).

## Caveats

Named errors are experimental. Check the
[roadmap](/docs/resources/roadmap) before relying on edge cases in production.

Error creation through `ensure`, type merging after `else`, and TypeScript
`_tag` output are still maturing. Treat generated payloads as evolving. See
[Generate client types](/docs/interop/invoke/generate-types#caveats).

## Examples

See the error handling examples on GitHub:

* [`examples/in/nominal_error.ft`](https://github.com/forst-lang/forst/blob/main/examples/in/nominal_error.ft)
* [`examples/in/union_error_types.ft`](https://github.com/forst-lang/forst/blob/main/examples/in/union_error_types.ft)

## Related

<CardGroup cols={2}>
  <Card title="Functions that can fail" icon="circle-nodes" href="/docs/language/result">
    Result returns and Ok / Err checks.
  </Card>

  <Card title="Check a value" icon="filter" href="/docs/language/check-a-value">
    How ensure connects checks to control flow.
  </Card>

  <Card title="List alternatives" icon="code-branch" href="/docs/language/union-and-intersection-types">
    Define a closed set of named errors.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.