Add problem-details: global exception handling with RFC 9457
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
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user