Files
pixa/internal/httpfetcher/request_failed_internal_test.go
T
clawbot 67205eb7a9
check / check (push) Canceled after 0s
Answer 502 for an upstream host with no address or a failed fetch (closes #367)
The image routes answered 500 and logged at error level when the upstream
host had no address, or when the fetch failed before the upstream
answered, such as on a refused connection. The fetcher now marks such a
failure with ErrUpstreamRequestFailed; a cancelled fetch is not marked.
respondImageError answers it, and ErrInvalidHost, 502 "upstream error"
and logs them at warn level. README Routes lists both under 502.

Model: opus-5-5
2026-11-11 21:13:39 +00:00

76 lines
1.7 KiB
Go

package httpfetcher
import (
"context"
"errors"
"net"
"syscall"
"testing"
"time"
)
// TestFetchFailedBeforeAnswer checks that a fetch whose connection is refused
// fails with ErrUpstreamRequestFailed, and that a fetch its caller cancels
// while connecting fails with context.Canceled and not with
// ErrUpstreamRequestFailed.
func TestFetchFailedBeforeAnswer(t *testing.T) {
t.Parallel()
tests := []struct {
name string
dial func(cancel context.CancelFunc) error
wantErr error
wantNotErr error
}{
{
name: "connection refused",
dial: func(context.CancelFunc) error {
return syscall.ECONNREFUSED
},
wantErr: ErrUpstreamRequestFailed,
wantNotErr: context.Canceled,
},
{
name: "cancelled while connecting",
dial: func(cancel context.CancelFunc) error {
cancel()
return context.Canceled
},
wantErr: context.Canceled,
wantNotErr: ErrUpstreamRequestFailed,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithCancel(testContext(t))
defer cancel()
f := New(&Config{
Timeout: 30 * time.Second,
MaxResponseSize: 50 << 20,
AllowHTTP: true,
MaxConnectionsPerHost: 20,
MaxConnections: 64,
DialContext: func(context.Context, string, string) (net.Conn, error) {
return nil, tt.dial(cancel)
},
})
_, err := f.Fetch(ctx, upstreamSource("/image"), "", "")
t.Logf("Fetch() error: %v", err)
if !errors.Is(err, tt.wantErr) {
t.Errorf("Fetch() error = %v, want %v", err, tt.wantErr)
}
if errors.Is(err, tt.wantNotErr) {
t.Errorf("Fetch() error = %v, must not be %v", err, tt.wantNotErr)
}
})
}
}