Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
# `routes/problem-json` — RFC 7807 problem+json helper
## Purpose
Bridges thrown errors from the route handlers into RFC 7807
`application/problem+json` responses. Reads the HTTP status from the
error's `context.statusCode` when present so the canonical
`ImportError` raised by the service / plugin layer surfaces with the
correct HTTP code without a code → status lookup table in the router.
Unknown throwables fall back to a generic 500 so the router never
crashes — the renderer is the safety net for non-`SuaveplanError`
exceptions that escape upstream code.
## Features
- `respondProblemJson(c, err)` — writes the `Response` to the Hono
context with `content-type: application/problem+json`.
- `renderProblem(err)` — pure render returning a `ProblemDetails`
object (used by tests + alt transports).
- `PROBLEM_JSON_CONTENT_TYPE` constant for downstream re-use.
- Native `Error` paths preserve the `name` so debugging upstream
failures stays readable.
## Usage: Basic Example
```ts
import { respondProblemJson } from "@suaveplan/api-plugin-import";
app.get("/foo", (c) => {
try {
throw new ImportError(IMPORT_CODES.NOT_FOUND, "missing", {
context: { statusCode: 404 },
});
} catch (err) {
return respondProblemJson(c, err);
}
});
```
## Usage: Advanced Example
```ts
import { renderProblem } from "@suaveplan/api-plugin-import";
// Pure render for use in alternate transports (gRPC adapter, queue worker)
const body = renderProblem(new Error("boom"));
// body === { type: "urn:suaveplan:error:internal", title: "Error", status: 500, detail: "boom" }
const message = JSON.stringify(body);
publishToDeadLetterQueue(message);
```
## API Reference
- `respondProblemJson(c: HonoLike, err: unknown): Response`
- `renderProblem(err: unknown): ProblemDetails`
- `interface HonoLike { header(name, value); body(data, status): Response }`
- `interface ProblemDetails { type; title; status; detail; code?; [k: string]: unknown }`
- `const PROBLEM_JSON_CONTENT_TYPE = "application/problem+json"`
## Implementation Notes
- The `type` field is built as `urn:suaveplan:error:<lowercased-code>`
so consumers can branch on the URN without parsing the body.
- Status hints below 400 (or missing) collapse to 500 — clients should
never receive a problem+json body with a 2xx status code.
- The `Error.name` fallback (`"InternalError"`) protects against
thrown objects whose `name` was wiped by a downstream serializer.
- `renderProblem` returns a `ProblemDetails` literal so consumers that
need to merge additional fields (e.g. `instance`) can spread it.