Return the context's error when it ends during a fetch request (closes #221)
check / check (push) Waiting to run
check / check (push) Waiting to run
retryingClient.get checked its context right after each request and returned that request's error, so a deadline that passed while a 503 was on its way came back as the 503. TestGetStopsWaitingWhenCanceled failed on that now and then on a loaded host. When the context ends before a retry, during the request or during the wait, get now returns an error wrapping both the context's error and the last try's error. The new test answers through a transport that holds the 503 until the context has ended. A real server cannot do that: the client drops a response still on its way when the context ends. Model: opus-5-5
This commit is contained in:
@@ -126,8 +126,9 @@ type retryingClient struct {
|
||||
// to a limit that doubles each time, unless the server's Retry-After
|
||||
// header says how long to wait. Any other failure, an error from use
|
||||
// included, is returned at once and unwrapped; a non-OK status is
|
||||
// returned as errHTTPStatus. use must start over each time it is called,
|
||||
// since a retry calls it again with a new response.
|
||||
// returned as errHTTPStatus. If ctx ends before a retry, the error wraps
|
||||
// both ctx's error and the last try's error. use must start over each
|
||||
// time it is called, since a retry calls it again with a new response.
|
||||
func (c retryingClient) get(
|
||||
ctx context.Context, rawURL string, use func(*http.Response) error,
|
||||
) error {
|
||||
@@ -169,15 +170,19 @@ func (c retryingClient) get(
|
||||
}
|
||||
}
|
||||
|
||||
if !retry || attempt == fetchAttempts || ctx.Err() != nil {
|
||||
if !retry || attempt == fetchAttempts {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Err() != nil {
|
||||
return fmt.Errorf("%w: %w", ctx.Err(), err)
|
||||
}
|
||||
|
||||
log.Warnf("%s: %s, retrying in %s", rawURL, err, wait.Round(time.Millisecond))
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
return fmt.Errorf("%w: %w", ctx.Err(), err)
|
||||
case <-time.After(wait):
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user