Skip to content

Commit

Permalink
Merge pull request #339 from mniehe/mn-check-context
Browse files Browse the repository at this point in the history
fix: Cancel retry if the request failed due to a cancelled context
  • Loading branch information
imroc authored Apr 7, 2024
2 parents 7e8e5f4 + 9953cc7 commit b4352e0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
22 changes: 19 additions & 3 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import (
"context"
"crypto/tls"
"errors"
"github.com/imroc/req/v3/internal/header"
"github.com/imroc/req/v3/internal/tests"
"golang.org/x/net/publicsuffix"
"io"
"net"
"net/http"
Expand All @@ -17,8 +14,27 @@ import (
"strings"
"testing"
"time"

"github.com/imroc/req/v3/internal/header"
"github.com/imroc/req/v3/internal/tests"
"golang.org/x/net/publicsuffix"
)

func TestRetryCancelledContext(t *testing.T) {
cancelledCtx, done := context.WithCancel(context.Background())
done()

client := tc().
SetCommonRetryCount(2).
SetCommonRetryBackoffInterval(1*time.Second, 5*time.Second)

res, err := client.R().SetContext(cancelledCtx).Get("/")

tests.AssertEqual(t, 0, res.Request.RetryAttempt)
tests.AssertNotNil(t, err)
tests.AssertErrorContains(t, err, "context canceled")
}

func TestWrapRoundTrip(t *testing.T) {
i, j, a, b := 0, 0, 0, 0
c := tc().WrapRoundTripFunc(func(rt RoundTripper) RoundTripFunc {
Expand Down
6 changes: 5 additions & 1 deletion request.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,13 +661,17 @@ func (r *Request) do() (resp *Response, err error) {
resp, err = r.client.roundTrip(r)
}

// Determine if the error is from a cancelled context. Store it here so it doesn't get lost
// when processing the AfterRespon middleware.
contextCanceled := errors.Is(err, context.Canceled)

for _, f := range r.afterResponse {
if err = f(r.client, resp); err != nil {
return
}
}

if r.retryOption == nil || (r.RetryAttempt >= r.retryOption.MaxRetries && r.retryOption.MaxRetries >= 0) { // absolutely cannot retry.
if contextCanceled || r.retryOption == nil || (r.RetryAttempt >= r.retryOption.MaxRetries && r.retryOption.MaxRetries >= 0) { // absolutely cannot retry.
return
}

Expand Down

0 comments on commit b4352e0

Please sign in to comment.