You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit f1160ed
Browse filesBrowse the repository at this point in the historyBrowse files
feat(openapi): configurable media type for error responses (#2337)
Closes#2317
Adds an `errorResponseContentType` option to `OpenAPIHandler` (and the
NestJS integration), `OpenAPILink` and `OpenAPIGenerator.generate()`.
Use it to send and document errors under a different media type, such as
`application/problem+json` for RFC 9457 Problem Details. Like the custom
error format options, set the same value on all three.
```ts
const handler = new OpenAPIHandler(router, {
customErrorResponseBodyEncoder: toProblemDetails,
errorResponseContentType: 'application/problem+json',
})
const link = new OpenAPILink(contract, {
errorResponseContentType: 'application/problem+json',
})
const spec = await generator.generate(router, {
customErrorResponseBodySchema: problemDetailsJsonSchema,
errorResponseContentType: 'application/problem+json',
})
```
## Changes
- **Handler:** when the option is set, `encodeError` sets the
`content-type` header. Since `@standard-server` 0.12.0 (#2342), a
`content-type` the response already sets on a JSON body is kept, and a
`standard-server: json` hint is added when that type would not otherwise
be read as JSON. Since #2344 the compression plugins keep it too.
- **NestJS:** works through the same codec, since `NestHandlerCodec`
extends `OpenAPIHandlerCodecCore`. Errors still go through Nest's
`HttpException` path, which keeps the content type (Nest appends `;
charset=utf-8`) and the `standard-server: json` hint.
- **Link:** an error response whose media type equals the option is read
with `resolveBody('json')`. The comparison ignores case and parameters
such as `charset`. Successful responses still use `responseBodyHint`,
and a non-JSON error page from a proxy still gives a
`MalformedResponseError`.
- **Generator:** error responses are documented under the configured
type instead of the hardcoded `application/json`.
- **Docs:** the handler, link and specification pages describe the
option.
Without the option, nothing changes.
## Tests
- Handler codec: `encodeError` sets the `content-type` header.
- Link codec: a table of cases. The link uses `'json'` for error
responses whose media type matches, ignoring case and parameters. It
uses no hint for other errors and keeps `responseBodyHint` for
successful responses.
- Generator: a unit test and an end-to-end test for the documented media
type.
- How adapters send the header is `@standard-server`'s behavior and is
covered by its tests, so there are no adapter-level tests here.
- `pnpm vitest run packages/openapi`, `tsc`, lint and `pnpm
docs:validate` all pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_012JepnhdVCkPJwexoiHyqRR
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: apps/content/docs/openapi/handler.mdx
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -249,6 +249,14 @@ const handler = new OpenAPIHandler(router, {
249
249
250
250
</Expandable>
251
251
252
+
Error responses are sent as `application/json` by default. Use `errorResponseContentType` to change the media type, such as `application/problem+json` for [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457):
If you use `OpenAPILink` with a custom server-side error format, make sure to configure [Custom Error Decoding](/docs/openapi/link#custom-error-decoding).
Copy file name to clipboardExpand all lines: apps/content/docs/openapi/link.mdx
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -242,6 +242,14 @@ const link = new OpenAPILink(contract, {
242
242
})
243
243
```
244
244
245
+
If the handler sets [`errorResponseContentType`](/docs/openapi/handler#custom-error-response), set the same value on the link so those error responses are parsed as JSON:
When the server answers with an error, `OpenAPILink` throws an `ORPCError` whose `cause` is a `ResponseError` carrying the resolved response, so details that are not part of the error itself, such as its status or headers, stay available (errors returned by [`customErrorResponseBodyDecoder`](#custom-error-decoding) are thrown as-is):
If the handler sets [`errorResponseContentType`](/docs/openapi/handler#custom-error-response), pass the same value to the generator so error responses are documented under that media type:
0 commit comments