2 Commits
Author SHA1 Message Date
sneak 0f788e05b7 Answer 499 to a client that goes away while waiting for an image (closes #339)
check / check (push) Canceled after 0s
When a request waits for an image another request is making and its
client goes away, the image proxy returns context.Canceled. serveImage
now answers it 499, the status nginx calls "client closed request". It
logs it once at info level with the request_id, host and path. It was
answered 500 and logged at error level, as pixa's own failure. A
cancellation while the request's context is live is still answered 500.
The request making the image is still answered as before. README.md
lists the 499 on both image routes.

Model: opus-5-5
2026-10-26 23:14:10 +00:00
sneak fc4c6b1a90 Test that a client leaving while another request makes its image gets 499
On both image routes, a request waits for an image another request is
making, and its client goes away. The first test wants that request
answered 499 and logged once at info level. It fails on next, which
answers 500 and logs it at error level. The second test pins the 500
that a cancellation keeps while the request's context is live; it
passes on next. The fix follows in the next commit.

Model: opus-5-5
2026-10-26 23:14:10 +00:00
@@ -58,13 +58,14 @@ func readLogLines(t *testing.T, logs *bytes.Buffer) []map[string]any {
return lines
}
// TestImageRoutes_ClientGoneAnswers499 checks that both image routes answer
// 499 to a request whose client goes away while its image is being made. A
// first request's fetch is held, so the image is being made, and a second
// request for the same image waits for it until its client goes away. The
// second request must be logged once at info level with its request ID and
// the source host and path. Nothing may be logged at error level.
func TestImageRoutes_ClientGoneAnswers499(t *testing.T) {
// TestImageRoutes_ClientGoneWhileWaitingAnswers499 checks that both image
// routes answer 499 to a request whose client goes away while it waits for an
// image another request is making. A first request's fetch is held, so the
// image is being made, and a second request for the same image waits for it
// until its client goes away. The second request must be logged once at info
// level with its request ID and the source host and path. Nothing may be
// logged at error level.
func TestImageRoutes_ClientGoneWhileWaitingAnswers499(t *testing.T) {
t.Parallel()
const requestID = "test-request-id"