# Passing a failure on: `attempt`

`attempt` passes every failure of a call on to your caller, so each one
must be in your own `fails` list. It starts a statement, and it works
only on a call that can fail ([Attempt](attempt.md)).

Here `reorder` reads an order, which can fail with `OrderNotFound`, and
reserves stock for it in another domain, which can fail with
`QuantityUnavailable`. It lists both:

```jadpo
use inventory/types { Reservation }
use inventory/failures { QuantityUnavailable }
use ordering/entities { Order }
use ordering/failures { OrderNotFound }
use inventory

action reorder(order_id: Order.id) fails OrderNotFound, QuantityUnavailable -> Reservation {
    var order: Order = attempt Order.get(order_id)  // can fail with OrderNotFound
    return attempt inventory.reserve_for_order(order)  // can fail with QuantityUnavailable
}
```

## Building a value at run time

Building a named type from a value known only at run time, such as
`Quantity(packs * 2)`, can break the type's rules. Its `attempt` maps each
rule that can break to a failure, in a block after the call:
`attempt Type(value) { max: SomeFailure }`. `invalid:` covers every rule
without an arm of its own
([Construction failures by rule](creating-values.md#construction-failures-by-rule)).

## When a value can't break its type

When the declared ranges prove a construction can't break any of the
target type's rules, it can't fail, so it takes no `attempt`. The `if`
conditions it sits under count as proof too
([Conditions as proof](creating-values.md#conditions-as-proof)).

```jadpo
function stock_needed(per_pack: Stock, packs: Quantity) -> Stock {
    var total: Stock = Stock(per_pack * packs)  // both at least 0, Stock has no maximum
    return total
}

function doubled(packs: Quantity) fails QuantityTooLarge -> Quantity {
    var result: Quantity = attempt Quantity(packs * 2) {  // at least 2, but can exceed 1000
        max: QuantityTooLarge
    }
    return result
}
```

In `stock_needed`, both values are at least 0 and `Stock` has no maximum,
so the result is always a valid `Stock`. In `doubled`, `packs * 2` is at
least 2 but can pass 1000, `Quantity`'s maximum, so it needs `attempt`
and an arm for `max`.
