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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ cross-test bleed. This function is not exposed via any HTTP route.

## Error responses

Handlers use a shared `sendError` helper so 400/404/413/500-style responses keep the canonical `{ error, message, requestId }` shape. The request id is attached before JSON parsing, which keeps body-parser errors correlated with the `X-Request-Id` response header.
Handlers use a typed `ApiError` taxonomy and one final `apiErrorHandler` mapping so each stable error code has one HTTP status and safe client message. Responses include `{ code, error, message, requestId }`; `error` is retained as a compatibility alias for clients that already branch on it. The request id is attached before JSON parsing, which keeps body-parser errors correlated with the `X-Request-Id` response header.

## Contributing

Expand Down
5 changes: 4 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,17 @@ All error responses share a single canonical JSON shape:

```json
{
"code": "invalid_request",
"error": "invalid_request",
"message": "human-readable explanation",
"requestId": "0f8c…-uuid"
}
```

Some errors include extra fields (e.g. the `500` handler adds `method`
and `path`), but `error`, `message`, and `requestId` are always present.
and `path`), but `code`, `error`, `message`, and `requestId` are always
present. `error` is a compatibility alias for `code`; new clients should prefer
`code`.

### Error codes

Expand Down
9 changes: 5 additions & 4 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ Sets four hardening headers on every response:
Registered `app.get/post/patch/delete` handlers. Each handler validates its inputs and calls `sendError` for client errors or `res.json` for success. Unhandled exceptions propagate to the error handler via `next(err)`.

**10. 404 catch-all**
An `app.use` registered after all routes returns a structured 404 using `sendError` for any path/method combination that did not match a route.
An `app.use` registered after all routes forwards an `ApiError("not_found")` for any path/method combination that did not match a route.

**11. Error handler** (4-argument `app.use`)
Catches any error passed to `next(err)` or thrown synchronously in a handler. Translates `entity.too.large` (body-parser overflow) into 413; all other errors become 500. The response always uses the canonical `{ error, message, requestId }` shape.
Catches any error passed to `next(err)` or thrown synchronously in a handler. The `API_ERROR_DEFINITIONS` taxonomy maps each stable `code` to one HTTP status and safe message, including parser errors such as `entity.too.large` and `entity.parse.failed`. Unexpected errors become `500 internal_error` without leaking internal details. The response always uses the canonical `{ code, error, message, requestId }` shape, where `error` is retained as a compatibility alias for `code`.

---

Expand Down Expand Up @@ -139,18 +139,19 @@ In all cases the `X-Request-Id` header is already set (layer 2 runs first), so t

## Canonical Error Envelope

Every error response — whether from a route handler, the 404 catch-all, or the global error handler — uses the same shape produced by `sendError` in `src/index.ts`:
Every error response — whether from a route handler, the 404 catch-all, or the global error handler — uses the same taxonomy-backed shape produced by `sendError` / `apiErrorHandler` in `src/index.ts`:

```jsonc
{
"code": "snake_case_error_code", // machine-readable
"error": "snake_case_error_code", // machine-readable
"message": "Human-readable detail.",
"requestId": "uuid-or-caller-supplied-id",
// optional extra fields (e.g. method, path on 500)
}
```

Clients can branch on `error` for programmatic handling and log `requestId` for cross-service tracing.
Clients can branch on `code` for programmatic handling and log `requestId` for cross-service tracing. Existing clients may continue using the `error` alias.

---

Expand Down
Loading