Skip to content

Commit

Permalink
wrap instead of replace
Browse files Browse the repository at this point in the history
Signed-off-by: Josh Humphries <[email protected]>
  • Loading branch information
jhump committed Sep 17, 2024
1 parent bcdb76e commit f1901be
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
3 changes: 1 addition & 2 deletions client_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,7 @@ func TestConnectionDropped(t *testing.T) {
}
err = svrStream.Err()
}
assert.NotNil(t, err)
if !assert.Equal(t, connect.CodeOf(err), connect.CodeUnavailable) {
if assert.NotNil(t, err) && !assert.Equal(t, connect.CodeOf(err), connect.CodeUnavailable) {
t.Logf("err = %v\n%#v", err, err)
}
})
Expand Down
6 changes: 1 addition & 5 deletions duplex_http_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,7 @@ func (d *duplexHTTPCall) makeRequest() {
// pipe. Write's check for io.ErrClosedPipe and will convert this to io.EOF.
response, err := d.httpClient.Do(d.request) //nolint:bodyclose
if err != nil {
if errors.Is(err, io.EOF) {
// We use io.EOF as a sentinel in many places and don't want this
// transport error to be confused for those other situations.
err = io.ErrUnexpectedEOF
}
err = wrapIfEOF(err)
err = wrapIfContextError(err)
err = wrapIfLikelyH2CNotConfiguredError(d.request, err)
err = wrapIfLikelyWithGRPCNotUsedError(err)
Expand Down
30 changes: 30 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
Expand Down Expand Up @@ -256,6 +257,22 @@ func (e *Error) detailsAsAny() []*anypb.Any {
return anys
}

type unexpectedEOFError struct {
err error
}

func (e *unexpectedEOFError) Error() string {
return e.err.Error()
}

func (e *unexpectedEOFError) Is(err error) bool {
// Return true only if err is the same value as e or if err
// is io.ErrUnexpectedEOF. Importantly, this returns false if
// the given err is io.EOF.
unexpectedEOF, ok := err.(*unexpectedEOFError)
return errors.Is(err, io.ErrUnexpectedEOF) || ok && e == unexpectedEOF
}

// IsNotModifiedError checks whether the supplied error indicates that the
// requested resource hasn't changed. It only returns true if the server used
// [NewNotModifiedError] in response to a Connect-protocol RPC made with an
Expand Down Expand Up @@ -292,6 +309,19 @@ func wrapIfUncoded(err error) error {
return NewError(CodeUnknown, maybeCodedErr)
}

// wrapIfEOF is used for abnormal EOF conditions, like EOF before response
// headers were received. When this happens, we want errors.Is(err, io.EOF) to
// return false (since we have *many* tests for io.EOF, which otherwise
// indicates a normal end of stream). Instead, the error will return true with
// errors.Is(err, io.ErrUnexpectedEOF), to make it more clear that the EOF is
// an abnormal end of the operation.
func wrapIfEOF(err error) error {
if errors.Is(err, io.EOF) {
return &unexpectedEOFError{err}
}
return err
}

// wrapIfContextError applies CodeCanceled or CodeDeadlineExceeded to Go's
// context.Canceled and context.DeadlineExceeded errors, but only if they
// haven't already been wrapped.
Expand Down

0 comments on commit f1901be

Please sign in to comment.