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

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, plus the values of credential-shaped
request headers, before rendering. Target configuration keeps
reaching the template only as a TargetView.

A body that reaches the cap is treated as cut whether or not SQLite
is what cut it. The delivery engine stops reading a response at its
own cap, which is the same number of bytes this page renders, and
the row it writes records that cut length as the whole length, so
nothing in the row separates a response that ended at the cap from
one severed there. Such a body goes through RedactCut, which drops
any tail that is a proper prefix of a secret: the remote chooses the
padding in front of a credential it echoes, so it chooses where the
cut falls inside that credential. Its marker says the response
reached the recording limit rather than quoting a total the row does
not know.

Redactors are built from an unscoped target load. Deleting a target
only soft deletes the row while its deliveries survive, and a scoped
load would leave exactly those deliveries rendering unredacted. The
views the page lists stay scoped.

Attempt loading is chunked so the IN clause cannot exceed SQLite's
bound-parameter limit, and a chunk that fails fails the page rather
than rendering the deliveries it covered as never having run. The
page renders at most 20 attempts per delivery, counting what it
leaves out.

static/css/tailwind.css is regenerated with tailwindcss for the
utility classes the new markup uses.
This commit is contained in:
2026-08-20 04:14:20 +00:00
parent 3b0ed826bc
commit 03c8e4616c
12 changed files with 1626 additions and 47 deletions

File diff suppressed because one or more lines are too long