Render delivery attempt detail in the event log (closes #202)
All checks were successful
check / check (push) Successful in 6m0s

Expanding a delivery on the event log page now shows each recorded
attempt: attempt number, outcome, status code, duration, error and
response body. Previously a failure rendered as "target: failed" and
diagnosing it meant opening the per-webhook SQLite file by hand.

The response body is cut by SQLite via substr over a blob cast, the
same projection the event body uses, so an oversized stored response
never becomes a Go string. The page reports the cut with a marker.

Response bodies and errors are remote content, so both go through a
new delivery.Redactor that strips the target's own destination URL,
path, query and userinfo before rendering. Configured HTTP header
values are deliberately not redacted; they are as often routine as
secret, and replacing them would mangle ordinary responses. Target
configuration keeps reaching the template only as a TargetView.
This commit is contained in:
2026-08-20 04:14:20 +00:00
parent 10c8dd2331
commit d9e8e28846
7 changed files with 861 additions and 19 deletions

View File

@@ -19,6 +19,10 @@ func (s *Handlers) SetLogForTest(log *slog.Logger) {
// to the handlers_test package.
const MaxRenderedBodyBytesForTest = maxRenderedBodyBytes
// MaxRenderedResponseBytesForTest exposes the event log's
// delivery response cap to the handlers_test package.
const MaxRenderedResponseBytesForTest = maxRenderedResponseBytes
// DummyVerificationsForTest reports how many equivalent-cost
// verifications were charged for usernames that do not exist. It
// lets a test prove the anti-enumeration path ran without timing