Expand description
One error body for the failures no handler writes (#5750).
Every handler failure is an ApiError, which
renders the shared ErrorResponse envelope. The responses produced
AROUND the handlers did not: an extractor rejection (a bad query string, a
request that is not multipart) was text/plain, and an unknown route, a
wrong method, the request timeout and the panic catcher answered with an
empty body. A client decoding {"error", "code"} got a JSON parse failure
on exactly those statuses. This layer rewrites them into the envelope,
keeping the status, every header but the body’s own, and the framework’s
message where it wrote one.
A JSON error body is left alone: ApiError has already written the
envelope, and the one other JSON non-2xx body, /api/v1/ready’s 503, is
a probe document whose status field is its contract.
Constants§
- MAX_
MESSAGE_ 🔒BYTES - The most of a framework-written body carried into
error. Rejection texts are a line or two; anything longer is not a message worth relaying.
Functions§
- code_
for_ 🔒status - The
codefor a status noApiErrorvariant chose. The statusesApiErroralso produces keep its spelling (INTERNAL_ERROR,FILE_TOO_LARGE,OVERLOADED), so a client branching on the code sees one name per condition whichever layer answered; the rest are the status’s reason phrase inSCREAMING_SNAKE(METHOD_NOT_ALLOWED,REQUEST_TIMEOUT). - envelope_
errors axum::middleware::map_responsetarget: wrap any non-JSON4xx/5xxin the shared error envelope.- is_json 🔒
- panic_
response - The
CatchPanicLayerresponse. That layer sits outside this one, so it renders the envelope itself, as anINTERNAL_ERROR. The panic payload is file-derived text and goes to the log, never to the client.