diff --git a/middleware.go b/middleware.go index 54798710..de3debd4 100644 --- a/middleware.go +++ b/middleware.go @@ -330,6 +330,7 @@ func parseResponseBody(c *Client, res *Response) (err error) { if IsJSONType(ct) || IsXMLType(ct) { // HTTP status code > 199 and < 300, considered as Result if res.IsSuccess() { + res.Request.Error = nil if res.Request.Result != nil { err = Unmarshalc(c, ct, res.body, res.Request.Result) return diff --git a/resty_test.go b/resty_test.go index 74d1142e..3569646d 100644 --- a/resty_test.go +++ b/resty_test.go @@ -81,6 +81,16 @@ func createGetServer(t *testing.T) *httptest.Server { _, _ = fmt.Fprintf(w, "%d", uint64(sinceLastRequest)) } atomic.AddInt32(&attempt, 1) + + case "/set-retry-error-recover": + w.Header().Set(hdrContentTypeKey, "application/json; charset=utf-8") + if atomic.LoadInt32(&attempt) == 0 { + w.WriteHeader(http.StatusTooManyRequests) + _, _ = w.Write([]byte(`{ "message": "too many" }`)) + } else { + _, _ = w.Write([]byte(`{ "message": "hello" }`)) + } + atomic.AddInt32(&attempt, 1) case "/set-timeout-test-with-sequence": seq := atomic.AddInt32(&sequence, 1) time.Sleep(time.Second * 2) diff --git a/retry_test.go b/retry_test.go index 5fcbec84..e5df0270 100644 --- a/retry_test.go +++ b/retry_test.go @@ -559,6 +559,37 @@ func TestClientRetryPost(t *testing.T) { } } +func TestClientRetryErrorRecover(t *testing.T) { + ts := createGetServer(t) + defer ts.Close() + + c := dc(). + SetRetryCount(2). + SetError(AuthError{}). + AddRetryCondition( + func(r *Response, _ error) bool { + err, ok := r.Error().(*AuthError) + retry := ok && r.StatusCode() == 429 && err.Message == "too many" + return retry + }, + ) + + resp, err := c.R(). + SetHeader(hdrContentTypeKey, "application/json; charset=utf-8"). + SetJSONEscapeHTML(false). + SetResult(AuthSuccess{}). + Get(ts.URL + "/set-retry-error-recover") + + assertError(t, err) + + authSuccess := resp.Result().(*AuthSuccess) + + assertEqual(t, http.StatusOK, resp.StatusCode()) + assertEqual(t, "hello", authSuccess.Message) + + assertNil(t, resp.Error()) +} + func filler(*Response, error) bool { return false }