Skip to content

Commit

Permalink
Mark EOF errors coming from http request as downstream (#1192)
Browse files Browse the repository at this point in the history
* Mark EOF errors comming from http request as downstream

* Fix comment

* Only http io.EOF errors are cosidered downstream

* Update comment
  • Loading branch information
ivanahuckova authored Jan 16, 2025
1 parent 2c603f5 commit 600e473
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
18 changes: 17 additions & 1 deletion experimental/status/status_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/x509"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/url"
Expand Down Expand Up @@ -142,7 +143,8 @@ func IsDownstreamHTTPError(err error) bool {
return IsDownstreamError(err) ||
isConnectionResetOrRefusedError(err) ||
isDNSNotFoundError(err) ||
isTLSCertificateVerificationError(err)
isTLSCertificateVerificationError(err) ||
isHTTPEOFError(err)
}

// InCancelledError returns true if err is context.Canceled or is gRPC status Canceled.
Expand Down Expand Up @@ -202,6 +204,20 @@ func isTLSCertificateVerificationError(err error) bool {
return false
}

// isHTTPEOFError returns true if the error is an EOF error inside of url.Error or net.OpError, indicating the connection was closed prematurely by server
func isHTTPEOFError(err error) bool {
var netErr *net.OpError
if errors.As(err, &netErr) {
return errors.Is(netErr.Err, io.EOF)
}

var urlErr *url.Error
if errors.As(err, &urlErr) {
return errors.Is(urlErr.Err, io.EOF)
}
return false
}

type sourceCtxKey struct{}

// SourceFromContext returns the source stored in the context.
Expand Down
31 changes: 31 additions & 0 deletions experimental/status/status_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/x509"
"errors"
"fmt"
"io"
"net"
"net/url"
"os"
Expand Down Expand Up @@ -248,6 +249,36 @@ func TestIsDownstreamHTTPError(t *testing.T) {
err: x509.UnknownAuthorityError{},
expected: true,
},
{
name: "nil error",
err: nil,
expected: false,
},
{
name: "io.EOF error",
err: io.EOF,
expected: false,
},
{
name: "url io.EOF error",
err: &url.Error{Op: "Get", URL: "https://example.com", Err: io.EOF},
expected: true,
},
{
name: "net op io.EOF error",
err: &net.OpError{Err: io.EOF},
expected: true,
},
{
name: "wrapped url io.EOF error",
err: fmt.Errorf("wrapped: %w", &url.Error{Op: "Get", URL: "https://example.com", Err: io.EOF}),
expected: true,
},
{
name: "joined error with io.EOF",
err: errors.Join(io.EOF, &url.Error{Op: "Get", URL: "https://example.com", Err: io.EOF}),
expected: true,
},
}
for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) {
Expand Down

0 comments on commit 600e473

Please sign in to comment.