Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 5 Nov 2026. What's built · Install 0.3.0
jadpo
ReferenceFailures

LanguageFailures

Declaring a failure

On this page

A failure is a way an action or query can fail that its caller is expected to handle, such as stock running out. You declare it as a type whose base is Failure, and raise it with reject. Save this as main.jadpo and run jadpo test main.jadpo:

example
/// There isn't enough stock to fill the order.type OutOfStock = Failure {    kind: FailureKind.conflict    message: "There isn't enough stock."}type Stock = Int {    min: 0}/// The stock left once one item is sold.function after_sale(stock: Stock) fails OutOfStock -> Stock {    if (stock == 0) {        reject OutOfStock    }    return Stock(stock - 1)}test "the last one sells, and then there are none" {    var left: Stock = attempt after_sale(1)    assert left == 0    assert after_sale(0) fails OutOfStock}

Failure, FailureKind and Int are built in. OutOfStock, Stock and after_sale are defined here. fails OutOfStock says the function can fail this way, and reject raises the failure.

The /// line above OutOfStock is a documentation comment. It is optional, and becomes the failure's description in generated documentation and OpenAPI.

The base, Failure, gives the type its settings: kind, message, client, internal and, rarely, code.

kind:, which sets the status

kind: names one of the failure kinds, the categories a failure falls into, such as not_found or conflict. The kind sets the HTTP status a client gets, and how background work, such as a job or an event subscriber, treats the failure. A failure never states a status itself.

The code clients see

A failure's public code is its name in lower_snake_case: TodoNotFound is todo_not_found. Clients rely on it, so it stays the same. Write code: "todo_missing" only to keep a code clients already use after you rename the failure.

message:

message: is fixed text that is safe to show anyone. It can't include values. Leave it out and the client gets the generic message Jadpo keeps for the failure's kind.

client: and internal: fields

A failure can carry values that say what went wrong, such as which product ran out. These are its fields, and they go in one of two blocks:

  • client: { } holds the fields sent to the caller.
  • internal: { } holds the fields that never leave the server. They are for your logs and traces.

Here are two failures with fields. Todo and Product are entities, kinds of stored record, declared with Quantity in another file of the app. A field typed Todo.id has the type of Todo's id field.

example
/// The todo does not exist.type TodoNotFound = Failure {    kind: FailureKind.not_found    message: "Todo not found."    internal: {        todo_id: Todo.id    }}type QuantityUnavailable = Failure {    kind: FailureKind.conflict    message: "The requested quantity is unavailable."    client: {        available: Quantity    }    internal: {        product_id: Product.id        requested: Quantity    }}

A field name can't be in both. A failure has no fields outside these two blocks. The caller gets a JSON body with code, message, request_id and, when the failure has client fields, those fields under details (How failures reach the client). Leave client out and the body has only the code, the message and the request id.

These fields are ordinary fields. A T? type, which may hold no value, is allowed. optional and default are not, because only Input types may have them (One form for every type).

Where the file goes

An app's code is split into domains: one business area each, such as planning, in a folder under domains/ (Project layout). Each failure has its own file in its domain's failures/ folder, such as domains/planning/failures/todo_not_found.jadpo.

When the actions of two or more domains can fail with the same failure, you put its file in shared/failures/ instead. When code in another domain handles the failure, for example in a match, write public before the declaration: public type QuantityUnavailable = Failure { ... }.

Markdown for agents: /docs/declaring-a-failure.md.Built from Jadpo main at aee2e8f.