From fb2a4c5378816f7b54de9d6d8cce9c3ad2a7496d Mon Sep 17 00:00:00 2001 From: Gavriel Hirsch Date: Mon, 25 Apr 2022 17:20:45 -0700 Subject: [PATCH 1/2] improve docs for response handlers --- README.md | 19 ------------------- client.go | 7 +++++-- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 09f5eaf..8943bec 100644 --- a/README.md +++ b/README.md @@ -45,25 +45,6 @@ The returned response object is an `*http.Response`, the same thing you would usually get from `net/http`. Had the request failed one or more times, the above call would block and retry with exponential backoff. -## Retrying cases that fail after a seeming success - -It's possible for a request to succeed in the sense that the expected response headers are received, but then to encounter network-level errors while reading the response body. In go-retryablehttp's most basic usage, this error would not be retryable, due to the out-of-band handling of the response body. In some cases it may be desirable to handle the response body as part of the retryable operation. - -A toy example (which will retry the full request and succeed on the second attempt) is shown below: - -```go -c := retryablehttp.NewClient() -r := retryablehttp.NewRequest("GET", "://foo", nil) -handlerShouldRetry := true -r.SetResponseHandler(func(*http.Response) error { - if !handlerShouldRetry { - return nil - } - handlerShouldRetry = false - return errors.New("retryable error") -}) -``` - ## Getting a stdlib `*http.Client` with retries It's possible to convert a `*retryablehttp.Client` directly to a `*http.Client`. diff --git a/client.go b/client.go index 57116e9..e75b649 100644 --- a/client.go +++ b/client.go @@ -80,8 +80,11 @@ var ( type ReaderFunc func() (io.Reader, error) // ResponseHandlerFunc is a type of function that takes in a Response, and does something with it. -// It only runs if the initial part of the request was successful. -// If an error is returned, the client's retry policy will be used to determine whether to retry the whole request. +// If an error is returned, the client's retry policy will be used to determine +// whether to retry the whole request (including this handler). +// NOTE: It only runs if the initial part of the request was successful. +// Make sure to check status codes! Even if the request was "successful" it may have a non-2xx status code. +// NOTE: If there is a response body, users should make sure to close it to avoid a memory leak. type ResponseHandlerFunc func(*http.Response) error // LenReader is an interface implemented by many in-memory io.Reader's. Used From b0b736350062d61f30b247294ce92c0ac888c06a Mon Sep 17 00:00:00 2001 From: Gavriel Hirsch Date: Tue, 10 May 2022 10:29:36 -0700 Subject: [PATCH 2/2] PR feedback --- client.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client.go b/client.go index e75b649..f40d241 100644 --- a/client.go +++ b/client.go @@ -80,11 +80,15 @@ var ( type ReaderFunc func() (io.Reader, error) // ResponseHandlerFunc is a type of function that takes in a Response, and does something with it. -// If an error is returned, the client's retry policy will be used to determine +// The ResponseHandlerFunc is called when the HTTP client successfully receives a response and the +// CheckRetry function indicates that a retry of the base request is not necessary. +// If an error is returned from this function, the CheckRetry policy will be used to determine // whether to retry the whole request (including this handler). -// NOTE: It only runs if the initial part of the request was successful. -// Make sure to check status codes! Even if the request was "successful" it may have a non-2xx status code. -// NOTE: If there is a response body, users should make sure to close it to avoid a memory leak. +// +// Make sure to check status codes! Even if the request was completed it may have a non-2xx status code. +// +// The response body is not automatically closed. It must be closed either by the ResponseHandlerFunc or +// by the caller out-of-band. Failure to do so will result in a memory leak. type ResponseHandlerFunc func(*http.Response) error // LenReader is an interface implemented by many in-memory io.Reader's. Used