Skip to content

Commit d6f66d0

Browse files
committed
Treat ECONNRESET and EPIPE as client disconnect
1 parent 2ad419c commit d6f66d0

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

internal/web/error.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"log/slog"
88
"net/http"
99
"strconv"
10+
"syscall"
1011
)
1112

1213
type ProblemDetails struct {
@@ -47,16 +48,18 @@ func InternalServerError(w http.ResponseWriter, detail string) {
4748
// ServerError logs the error and writes a 500 response, unless the error
4849
// is due to a canceled context (client disconnect), in which case it's a no-op.
4950
func ServerError(w http.ResponseWriter, msg string, err error) {
50-
if errors.Is(err, context.Canceled) {
51+
if IsClientDisconnect(err) {
5152
return
5253
}
5354
slog.Error(msg, "error", err)
5455
InternalServerError(w, "internal server error")
5556
}
5657

57-
// IsClientDisconnect reports whether the error is due to a canceled context.
58+
// IsClientDisconnect reports whether the error is due to a client disconnecting.
5859
func IsClientDisconnect(err error) bool {
59-
return errors.Is(err, context.Canceled)
60+
return errors.Is(err, context.Canceled) ||
61+
errors.Is(err, syscall.ECONNRESET) ||
62+
errors.Is(err, syscall.EPIPE)
6063
}
6164

6265
func TooManyRequests(w http.ResponseWriter, detail string, retryAfterSeconds int) {

internal/web/error_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"net/http"
99
"net/http/httptest"
10+
"syscall"
1011
"testing"
1112
)
1213

@@ -96,6 +97,10 @@ func TestIsClientDisconnect(t *testing.T) {
9697
}{
9798
{"context.Canceled", context.Canceled, true},
9899
{"wrapped context.Canceled", fmt.Errorf("scan: %w", context.Canceled), true},
100+
{"ECONNRESET", syscall.ECONNRESET, true},
101+
{"wrapped ECONNRESET", fmt.Errorf("write: %w", syscall.ECONNRESET), true},
102+
{"EPIPE", syscall.EPIPE, true},
103+
{"wrapped EPIPE", fmt.Errorf("write: %w", syscall.EPIPE), true},
99104
{"generic error", errors.New("timeout"), false},
100105
{"nil", nil, false},
101106
}

0 commit comments

Comments
 (0)