Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/lint.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -382,6 +382,21 @@ jobs:
- name: Error-code casing guard
run: pnpm check:error-code-casing

# #8967: the docs publish an HTTP status per error code and the doors decide
# it; nothing reconciled the two. `MISSING_REQUIRED_FIELD` was documented 400
# in both pages while five controlled_by_parent refusals answered 422 — on a
# public error contract, with CI green the whole time, found only by a human
# reading a PR. The runtime side is DERIVED (error classes' `readonly status`,
# both `sendError` doors, `HttpStatusErrorCodeMap`), never a second hand-written
# table, and the assertion is a set comparison in BOTH directions so a code may
# legitimately carry more than one documented status. Runs its own --self-test
# first, which pins the real pre-fix doc text as a red case. Placed beside the
# other ADR-0112 error-vocabulary guards, and deliberately in a job with no
# `paths:` filter — either side of this reconciliation can move it, so filtering
# on `packages/**` or on `content/**` would blind it to half its own subject.
- name: Documented HTTP status matches the status the runtime emits
run: pnpm check:error-status-conformance

# Namespace-wildcard fall-through guard (#4116). A handler mounted on
# `<prefix>/*` claims the whole namespace, and Hono's first-registered
# handler that answers wins — so a TERMINAL wildcard makes every other
Expand Down
14 changes: 12 additions & 2 deletions content/docs/api/error-catalog.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -404,7 +404,15 @@ an environment scope (no `X-Environment-Id` header and no hostname mapping).

---

## Server Errors (500)
## Server Errors (5xx)

The heading is `5xx`, not `500`, because these five codes are not all served with
the same status: `TIMEOUT` is the code a `504` carries and `NOT_IMPLEMENTED` the
code a `501` carries (`HttpStatusErrorCodeMap`, `packages/spec/src/api/errors.zod.ts`),
and `SERVICE_UNAVAILABLE` is a `503`. The per-code status is in the
[quick reference](#http-status-quick-reference) at the end of this page, and
`pnpm check:error-status-conformance` reconciles every row there against what the
runtime can actually emit.

### `INTERNAL_ERROR`
**Cause:** An unexpected server-side error occurred.
Expand DownExpand Up@@ -673,6 +681,8 @@ async function handleApiCall() {
| 409 | `conflict` | `CONCURRENT_MODIFICATION`, `DUPLICATE_RECORD`, `DELETE_RESTRICTED` |
| 422 | `validation` | `MISSING_REQUIRED_FIELD` on an absent `controlled_by_parent` master reference (see [above](#missing_required_field)) — this row is an exception to the 400 row, not a second home for the code |
| 429 | `rate_limit` | `RATE_LIMIT_EXCEEDED`, `QUOTA_EXCEEDED` |
| 500 | `server` | `INTERNAL_ERROR`, `DATABASE_ERROR`, `TIMEOUT` |
| 500 | `server` | `INTERNAL_ERROR`, `DATABASE_ERROR` |
| 501 | `server` | `NOT_IMPLEMENTED` — the storage routes answer it when the adapter cannot issue presigned URLs |
| 502 | `external` | `EXTERNAL_SERVICE_ERROR`, `INTEGRATION_ERROR` |
| 503 | `maintenance` | `SERVICE_UNAVAILABLE` |
| 504 | `server` | `TIMEOUT` — the status this code names; no route answers `TIMEOUT` with `500` |
1 change: 1 addition & 0 deletions package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -62,6 +62,7 @@
"check:service-providers": "node scripts/check-service-providers.mjs",
"check:route-envelope": "node scripts/check-route-envelope.mjs --self-test && node scripts/check-route-envelope.mjs",
"check:error-code-casing": "node scripts/check-error-code-casing.mjs --self-test && node scripts/check-error-code-casing.mjs",
"check:error-status-conformance": "node scripts/check-error-status-conformance.mjs --self-test && node scripts/check-error-status-conformance.mjs",
"check:wildcard-fallthrough": "node scripts/check-wildcard-fallthrough.mjs --self-test && node scripts/check-wildcard-fallthrough.mjs",
"check:meta-type-normalized": "node scripts/check-meta-type-normalized.mjs --self-test && node scripts/check-meta-type-normalized.mjs",
"check:filter-alias-parity": "node scripts/check-filter-alias-parity.mjs --self-test && node scripts/check-filter-alias-parity.mjs",
Expand Down
Loading
Loading