fix(14.2): WR-02 499 only for a 5xx caused by the client going away

Every 5xx became 499 once the request context was cancelled, so a panic or
a real database error on a request the browser had abandoned passed the
phase gate's 5xx scan. Now a 5xx is logged as 499 only when the client had
already gone when the status was written and the handler did not panic;
recoverJSON and recoverBare mark the access log entry. Every record of an
abandoned request carries client_gone=true. The gate self-test plants a
5xx with client_gone=true and must refuse it.
This commit is contained in:
2026-10-12 11:19:12 +02:00
parent fbcfaaf05f
commit c30145ed25
6 changed files with 123 additions and 39 deletions

View File

@@ -185,7 +185,8 @@ run_regex() {
}
# scan_go_log FILE refuses a silent search fallback or a 5xx request record
# (research G8, D-12). A 499 (client closed the request) is not a 5xx.
# (research G8, D-12). A 499 (the surf access log's status for a 5xx caused
# by the client going away) is not a 5xx; a 5xx with client_gone=true is.
scan_go_log() {
local file="$1" hits
[[ -f "$file" ]] || {
@@ -299,11 +300,13 @@ run_self_test() {
local dir
dir="$(mktemp -d)"
printf '%s\n' '[go] level=INFO msg="http request" method=GET pattern="GET /a" status=200 duration_ms=1' \
'[go] level=INFO msg="http request" method=GET pattern="GET /b" status=499 duration_ms=3' >"$dir/clean.log"
'[go] level=INFO msg="http request" method=GET pattern="GET /b" status=499 duration_ms=3 client_gone=true' >"$dir/clean.log"
printf '%s\n' '[go] level=INFO msg="http request" method=GET pattern="GET /a" status=503 duration_ms=1' >"$dir/5xx.log"
printf '%s\n' '[go] level=INFO msg="http request" method=GET pattern="GET /a" status=500 duration_ms=1 client_gone=true' >"$dir/5xx-gone.log"
printf '%s\n' '[go] level=WARN msg="album search engine failed" err=timeout' >"$dir/search.log"
expect_status go-log-clean 0 scan_go_log "$dir/clean.log"
expect_status go-log-5xx 1 scan_go_log "$dir/5xx.log"
expect_status go-log-5xx-client-gone 1 scan_go_log "$dir/5xx-gone.log"
expect_status go-log-search 1 scan_go_log "$dir/search.log"
expect_status go-log-missing 1 scan_go_log "$dir/absent.log"
printf '# tests 9\n# pass 9\n# fail 0\n# cancelled 0\n# skipped 0\n# todo 0\n' >"$dir/tap-clean"