Kinds
Every failure has a kind, which decides the HTTP status a client gets and
what the failure means. A kind is a FailureKind value, written
FailureKind.not_found (Enums).
You can declare seven of the kinds. The runtime raises the other eight
itself, and declaring one of those is the error
failure.kind_runtime_only.
| Kind | HTTP | Meaning | Raised by |
|---|---|---|---|
invalid_request |
400 | The request could not be read (bad JSON, wrong shape) | runtime |
invalid_value |
422 | A well-formed value breaks a rule | you; the runtime for request input |
unauthenticated |
401 | No valid identity | runtime (Identity) |
not_permitted |
403 | The caller is known but may not do this | you; policy |
not_visible |
404 | Hidden from this caller | policy only (Concealing records) |
not_found |
404 | The record does not exist | you |
conflict |
409 | The current state conflicts with the request | you |
precondition_failed |
412 | An HTTP precondition such as If-Match failed |
runtime (HTTP) |
rejected |
422 | A business rule refused the operation | you |
rate_limited |
429 | Wait before retrying | you; runtime |
unavailable |
503 | A dependency is temporarily unavailable | you; runtime |
timed_out |
504 | A dependency or deadline ran out of time | runtime |
outcome_unknown |
500 | The change may or may not have happened, so retrying blindly is unsafe | runtime |
misconfigured |
500 | Deployment configuration is wrong | runtime |
internal_fault |
500 | A defect | runtime |
Here CheckoutUnavailable is fine, because a checkout that is briefly
unavailable is a business outcome callers handle. Broken is refused,
because only the runtime raises internal_fault:
type CheckoutUnavailable = Failure { kind: FailureKind.unavailable // fine: a business outcome callers handle message: "Checkout is temporarily unavailable."}type Broken = Failure { kind: FailureKind.internal_fault // error: only the runtime raises internal_fault (question 3)}
error: `Broken` can't have the kind `internal_fault` --> main.jadpo:7:11 |7 | kind: FailureKind.internal_fault // error: only the runtime raises internal_fault (question 3) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ raised only by the runtime reason: The runtime raises `internal_fault` itself; an application declares `invalid_value`, `not_found`, `not_permitted`, `conflict`, `rejected`, `rate_limited` and `unavailable`, so a client's status always means the same thing. next: Use the kind an application declares that fits this outcome (agent) rule: failure.kind_runtime_only help: https://jadpo.dev/docs/errors/failure.kind_runtime_onlycheck failed: 1 error, 1 file
invalid_value and rejected both use 422, and 400 is kept for requests
that can't be read at all. An application can't add a kind or choose a
status. If no kind fits, that is a change to the language, not to your
app.
Markdown for agents: /docs/kinds.md.Built from Jadpo main at a707efb.