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:
2026-09-11 17:12:22 +00:00
co-authored by Claude Opus 5
parent a065696478
commit 926250e1a9
63 changed files with 2414 additions and 0 deletions
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Is the unexpected exception LOGGED? Counts log lines mentioning it after one request.
# -> docs/output/silent-500.txt
set -uo pipefail
source "$(dirname "$0")/env.sh"
probe() { # label, profiles, extra args, path, header
local label="$1" profiles="$2" extra="$3" path="$4" header="${5:-}"
EXTRA_ARGS="$extra" "$MODULE_DIR/scripts/run.sh" "$profiles" || exit 1
local before; before=$(wc -l < "$LOG")
curl -s -o /dev/null ${header:+-H "$header"} "$BASE$path"
sleep 1
local lines; lines=$(tail -n +"$((before+1))" "$LOG" | grep -v 'Picked up JAVA_TOOL_OPTIONS')
local errors; errors=$(echo "$lines" | grep -c ' ERROR ' || true)
local traces; traces=$(echo "$lines" | grep -c '^ at ' || true)
printf '%-58s ERROR lines: %-3s stack frames: %s\n' "$label" "$errors" "$traces"
echo "$lines" | grep ' ERROR ' | sed 's/^.* ERROR / ERROR /' | cut -c1-200 | head -2
}
{
echo "# One request to an endpoint that throws IllegalStateException. What reaches the log?"
echo
probe "defaults (Boot /error)" "" "" /orders/boom
probe "boot-flag" "boot-flag" "" /orders/boom
probe "advice, catch-all logs with errorId" "advice" "" /orders/boom
probe "advice, catch-all WITHOUT the log line" "advice" "--demo.problems.log-unhandled=false" /orders/boom
probe "catchall-first (returns 500, never logs)" "catchall-first" "" /orders/boom
echo
echo "# And for an exception thrown by a servlet filter (never reaches any advice):"
echo
probe "advice,errors - filter exception" "advice,errors" "" /orders/1 "X-Tenant: BAD!"
} > "$OUT/silent-500.txt"
"$MODULE_DIR/scripts/stop.sh"
cat "$OUT/silent-500.txt"