Skip to content

hono adapter: render an escaped throw that carries a declared ADR-0112 status + registered code as that envelope, not as bare 500 INTERNAL_ERROR "No response from handler" — #15999's shared half #16545

Description

@os-zhuang

Split from #15999 by the director seat (2026-09-07) — the domain:cli half that the #15999 ruling (decision batch #55, maintainer 「同意」, comment 5559668176) said triage would split and that sat unsplit for 14 hours under pm:retriage. The ruling is the specification; this card carries item 2 of it.

What is ruled (verbatim from the #15999 ruling, item 2)

Shared half (domain:cli, hono adapter / registrar wrapper): an escaped throw carrying a declared ADR-0112 status + registered code is rendered by them, not as a bare 500 INTERNAL_ERROR "No response from handler". This changes what an escaped throw means for every direct-mount route; the PR pins that an escaped non-envelope throw still answers 500 with no cause in the body.

Measured starting point (from #15999)

Landing shape

  • One place: the adapter (or the registrar wrapper it already funnels through — measure which one every direct-mount route actually passes) recognises an escaped error whose status is a declared ADR-0112 status and whose code is registered in ERROR_CODE_LEDGER / StandardErrorCode, and answers that envelope. ⛔ An escaped throw that is not such an envelope keeps today's behaviour exactly — 500, no cause in the body — and that is pinned in the same PR (both directions).
  • ⛔ No new error code, no ledger row (the codes involved are already registered) ⇒ Clause-②: no as a contract door; the response for an already-declared envelope becomes what its declaration says. If measurement shows a code on this path is not registered, stop and report — that is a ledger gap under the [Decision] Clause ② on an UNREGISTERED error code carried by a thrown value: #14552 landed no, #15963 lands yes, and they are the same class #16404 ruling, not something to register in passing.
  • Serial with the per-family half on service-datasource: the AuthzStoreUnavailableError the admin guard re-raises reaches the wire as 500 INTERNAL_ERROR, not the 503 SERVICE_UNAVAILABLE the brand declares #15999 (settings' three route catches; storage's authorizeDownload inner catch { deny }): that half makes the brand reach this render; this half makes the render correct. Either may land first; the datasource family is the one that exercises this card end-to-end today, so the pin drives GET /api/v1/datasources with a tenancy service registered through a throwing factory and asserts 503 SERVICE_UNAVAILABLE on the wire.
  • Existing security pins assert the outage class (status ∈ {500, 503}, never 200, never 403) and stay green.

Refs: #15999 (ruling, measurements for datasource / settings / storage) · #13279 · #6504 (badRequest already relays a service-thrown 503 envelope in the same file) · #16018 (docs page blocked on the outage status being promisable).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions