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
26 lines
1.5 KiB
Markdown
26 lines
1.5 KiB
Markdown
# 7. Silent 500s: the catch-all that makes errors invisible
|
|
|
|
[← 6. Outside Spring MVC](06-outside-mvc.md) · [Index](../README.md) · Next: [8. Clients →](08-clients.md)
|
|
|
|
When an exception reaches the container, Tomcat logs it with its stack trace. When an
|
|
`@ExceptionHandler` handles it, **nothing logs it unless that handler does** - handling an
|
|
exception means it is no longer an error as far as the framework is concerned.
|
|
|
|
[`silent-500.txt`](output/silent-500.txt), one request to `/orders/boom` per setup:
|
|
|
|
```
|
|
defaults (Boot /error) ERROR lines: 1 stack frames: 87
|
|
boot-flag ERROR lines: 1 stack frames: 87
|
|
advice, catch-all logs with errorId ERROR lines: 1 stack frames: 87
|
|
advice, catch-all WITHOUT the log line ERROR lines: 0 stack frames: 0
|
|
catchall-first (returns 500, never logs) ERROR lines: 0 stack frames: 0
|
|
```
|
|
|
|
The last two return a tidy `500` problem and leave no trace anywhere. Adding problem details to an
|
|
API that used to log its failures can remove the only record of them.
|
|
|
|
[`GlobalExceptionHandler.unexpected`](../src/main/java/com/ankurm/problems/advice/GlobalExceptionHandler.java)
|
|
logs at ERROR with a generated `errorId`, puts the same id in the response, and keeps
|
|
`ex.getMessage()` out of it - the message in this project contains a JDBC URL and a database user,
|
|
which is exactly what RFC 9457's security considerations warn against exposing.
|