Companion code for "Global Exception Handling with ProblemDetail (RFC 9457) in Spring Boot 4". Thirteen failures under five handling setups (Boot defaults, the Boot flag, a ResponseEntityExceptionHandler advice, advice plus an ErrorController, a catch-all ordered first), validation errors, i18n, content negotiation, Security's 401/403, silent 500s and decoding on the client. 16 tests pin the behaviour. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01C3TETMrqVUWeFkNtz3Jbo3
1.6 KiB
8. The client side: decoding problems with RestClient
RestClient's default status handler throws HttpClientErrorException /
HttpServerErrorException; getResponseBodyAs(ProblemDetail.class) decodes the body with the
client's converters. /diag/decode
reports what came back (client-decoding.txt).
What works
Extension members land in getProperties() - orderId, the errors list, errorId. The mixin
works in both directions.
Two things to code defensively against
getType() is null when the server omitted it, which Spring Framework 7 servers do for every
framework error (chapter 4). Treat null as about:blank.
Decoding succeeds on a body that is not a problem at all. Against the defaults profile the
server sends Boot's application/json error, and it still decodes:
"exception": "org.springframework.web.client.HttpServerErrorException$InternalServerError",
"status": 500,
"contentType": "application/json",
"problemDetail": {
"type": "null",
"title": "Internal Server Error",
"status": 500,
"detail": null,
"instance": "null",
"properties": {
"timestamp": "2026-09-11T17:05:01.408Z",
"error": "Internal Server Error",
"path": "/orders/999"
}
}
Unknown members go into properties, so any JSON object "is" a ProblemDetail. Check the
Content-Type is application/problem+json before believing you have one.