(statusCode int, r io.Reader)
| 64 | } |
| 65 | |
| 66 | func parseHTTPErrorResponse(statusCode int, r io.Reader) error { |
| 67 | var errors errcode.Errors |
| 68 | body, err := io.ReadAll(r) |
| 69 | if err != nil { |
| 70 | return err |
| 71 | } |
| 72 | |
| 73 | // For backward compatibility, handle irregularly formatted |
| 74 | // messages that contain a "details" field. |
| 75 | var detailsErr struct { |
| 76 | Details string `json:"details"` |
| 77 | } |
| 78 | err = json.Unmarshal(body, &detailsErr) |
| 79 | if err == nil && detailsErr.Details != "" { |
| 80 | switch statusCode { |
| 81 | case http.StatusUnauthorized: |
| 82 | return errcode.ErrorCodeUnauthorized.WithMessage(detailsErr.Details) |
| 83 | case http.StatusTooManyRequests: |
| 84 | return errcode.ErrorCodeTooManyRequests.WithMessage(detailsErr.Details) |
| 85 | default: |
| 86 | return errcode.ErrorCodeUnknown.WithMessage(detailsErr.Details) |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | if err := json.Unmarshal(body, &errors); err != nil { |
| 91 | return &unexpectedHTTPResponseError{ |
| 92 | ParseErr: err, |
| 93 | StatusCode: statusCode, |
| 94 | Response: body, |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | if len(errors) == 0 { |
| 99 | // If there was no error specified in the body, return |
| 100 | // UnexpectedHTTPResponseError. |
| 101 | return &unexpectedHTTPResponseError{ |
| 102 | ParseErr: errNoErrorsInBody, |
| 103 | StatusCode: statusCode, |
| 104 | Response: body, |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | return errors |
| 109 | } |
| 110 | |
| 111 | func makeErrorList(err error) []error { |
| 112 | if errL, ok := err.(errcode.Errors); ok { |
no outgoing calls
no test coverage detected
searching dependent graphs…