# Errors

What went wrong, told to the caller. Returned with [`fail()`](https://www.prongs.dev/docs/profiles/errors.md).

Raised with: [`fail()`](https://www.prongs.dev/docs/profiles/errors.md) · Added with: `npx prongs add errors` · Domains: [7](#domains) · Intents: [15](#domains)

## Domains

- [`request.*`](https://www.prongs.dev/docs/intents/request.md) Request: The caller’s request was wrong: unreadable, incomplete, or a value that breaks a rule. 400 or 422. (400, 422; 3 intents)
- [`auth.*`](https://www.prongs.dev/docs/intents/auth.md) Auth: No valid credentials: nobody signed in, an expired session, a bad token or secret. 401. (401; 4 intents)
- [`permission.*`](https://www.prongs.dev/docs/intents/permission.md) Permission: Valid credentials, but not allowed to do this. 403. (403; 1 intent)
- [`record.*`](https://www.prongs.dev/docs/intents/record.md) Record: The thing asked for is not there, as far as the caller may know. 404. (404; 1 intent)
- [`conflict.*`](https://www.prongs.dev/docs/intents/conflict.md) Conflict: The request clashes with the current state: it already exists, or it is not possible yet. 409. (409; 2 intents)
- [`limit.*`](https://www.prongs.dev/docs/intents/limit.md) Limit: Too many requests, or an allowance used up. 429. (429; 1 intent)
- [`failure.*`](https://www.prongs.dev/docs/intents/failure.md) Failure: Our fault or a dependency’s. The caller sees a generic message; the details are logged. 5xx. (500, 502, 503; 3 intents)

## Raising one

`fail(intent, message?, options?)` returns the `Response`: `{ ok: false, error, code }` with the intent’s status. Name what went wrong; the intent sets the status, the message the caller sees, and any log it writes. [Read the guide](https://www.prongs.dev/docs/profiles/errors.md).

```ts
// The request cannot be read: invalid JSON, the wrong content type
return fail('request.malformed', 'Invalid JSON.');

// A required field or parameter is absent
return fail('request.missing', 'Handle is required.');

// A field breaks a rule: too long, the wrong format, out of range
return fail('request.invalid', 'Use 1–32 lowercase letters, numbers, or hyphens.');
```

## Looks

The statuses error intents are built from. Change a status here and every error built from it follows. Looks have no pages of their own; each is listed here with what it is built from and the intents built from it.

### [`status.*`](https://www.prongs.dev/docs/intents/errors.md#status)
- [`status.badrequest`](https://www.prongs.dev/docs/intents/errors.md#status-badrequest): 400: the request was wrong; the caller sees your message
  - Used to build: [`request.malformed`](https://www.prongs.dev/docs/intents/request/malformed.md), [`request.missing`](https://www.prongs.dev/docs/intents/request/missing.md)
- [`status.unprocessable`](https://www.prongs.dev/docs/intents/errors.md#status-unprocessable): 422: the request was readable but a value breaks a rule
  - Used to build: [`request.invalid`](https://www.prongs.dev/docs/intents/request/invalid.md)
- [`status.unauthorized`](https://www.prongs.dev/docs/intents/errors.md#status-unauthorized): 401: no valid credentials
  - Used to build: [`auth.required`](https://www.prongs.dev/docs/intents/auth/required.md), [`auth.expired`](https://www.prongs.dev/docs/intents/auth/expired.md), [`auth.signin`](https://www.prongs.dev/docs/intents/auth/signin.md), [`auth.invalid`](https://www.prongs.dev/docs/intents/auth/invalid.md)
- [`status.forbidden`](https://www.prongs.dev/docs/intents/errors.md#status-forbidden): 403: valid credentials, not allowed
  - Used to build: [`permission.denied`](https://www.prongs.dev/docs/intents/permission/denied.md)
- [`status.notfound`](https://www.prongs.dev/docs/intents/errors.md#status-notfound): 404: nothing there, as far as the caller may know
  - Used to build: [`record.missing`](https://www.prongs.dev/docs/intents/record/missing.md)
- [`status.conflict`](https://www.prongs.dev/docs/intents/errors.md#status-conflict): 409: clashes with the current state
  - Used to build: [`conflict.duplicate`](https://www.prongs.dev/docs/intents/conflict/duplicate.md), [`conflict.state`](https://www.prongs.dev/docs/intents/conflict/state.md)
- [`status.toomany`](https://www.prongs.dev/docs/intents/errors.md#status-toomany): 429: too many requests or too much use
  - Used to build: [`limit.rate`](https://www.prongs.dev/docs/intents/limit/rate.md)
- [`status.internal`](https://www.prongs.dev/docs/intents/errors.md#status-internal): 500: our fault; the caller sees a generic message
  - Used to build: [`failure.internal`](https://www.prongs.dev/docs/intents/failure/internal.md)
- [`status.badgateway`](https://www.prongs.dev/docs/intents/errors.md#status-badgateway): 502: a dependency failed; the caller sees a generic message
  - Used to build: [`failure.upstream`](https://www.prongs.dev/docs/intents/failure/upstream.md)
- [`status.unavailable`](https://www.prongs.dev/docs/intents/errors.md#status-unavailable): 503: not available right now; the caller may retry
  - Used to build: [`failure.unavailable`](https://www.prongs.dev/docs/intents/failure/unavailable.md)

## For registry authors

**Starter intents.** These are the intents `prongs add errors` puts in your registry, raised with [`fail()`](https://www.prongs.dev/docs/profiles/errors.md). Change the messages to suit your app, and the statuses through the [`status.*`](https://www.prongs.dev/docs/intents/errors.md#status) intents they are built from.
