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
43 lines
1.6 KiB
Markdown
43 lines
1.6 KiB
Markdown
# 8. The client side: decoding problems with `RestClient`
|
|
|
|
[← 7. Silent 500s](07-silent-500s.md) · [Index](../README.md)
|
|
|
|
`RestClient`'s default status handler throws `HttpClientErrorException` /
|
|
`HttpServerErrorException`; `getResponseBodyAs(ProblemDetail.class)` decodes the body with the
|
|
client's converters. [`/diag/decode`](../src/main/java/com/ankurm/problems/diag/DiagController.java)
|
|
reports what came back ([`client-decoding.txt`](output/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](04-i18n-and-types.md)). 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.
|