Skip to content

Commit

Permalink
Actually retry retryable status codes (#1618)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonjohnsonjr committed Mar 29, 2023
1 parent 21ac1b2 commit e2620e5
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
27 changes: 25 additions & 2 deletions pkg/v1/remote/transport/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ type Error struct {
Request *http.Request
// The raw body if we couldn't understand it.
rawBody string

// Bit of a hack to make it easier to force a retry.
temporary bool
}

// Check that Error implements error
Expand Down Expand Up @@ -72,6 +75,10 @@ func (e *Error) responseErr() string {

// Temporary returns whether the request that preceded the error is temporary.
func (e *Error) Temporary() bool {
if e.temporary {
return true
}

if len(e.Errors) == 0 {
_, ok := temporaryStatusCodes[e.StatusCode]
return ok
Expand Down Expand Up @@ -153,21 +160,37 @@ func CheckError(resp *http.Response, codes ...int) error {
return nil
}
}

b, err := io.ReadAll(resp.Body)
if err != nil {
return err
}

return makeError(resp, b)
}

func makeError(resp *http.Response, body []byte) *Error {
// https://github.com/docker/distribution/blob/master/docs/spec/api.md#errors
structuredError := &Error{}

// This can fail if e.g. the response body is not valid JSON. That's fine,
// we'll construct an appropriate error string from the body and status code.
_ = json.Unmarshal(b, structuredError)
_ = json.Unmarshal(body, structuredError)

structuredError.rawBody = string(b)
structuredError.rawBody = string(body)
structuredError.StatusCode = resp.StatusCode
structuredError.Request = resp.Request

return structuredError
}

func retryError(resp *http.Response) error {
b, err := io.ReadAll(resp.Body)
if err != nil {
return err
}

rerr := makeError(resp, b)
rerr.temporary = true
return rerr
}
2 changes: 1 addition & 1 deletion pkg/v1/remote/transport/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (t *retryTransport) RoundTrip(in *http.Request) (out *http.Response, err er
if out != nil {
for _, code := range t.codes {
if out.StatusCode == code {
return CheckError(out)
return retryError(out)
}
}
}
Expand Down

0 comments on commit e2620e5

Please sign in to comment.