diff --git a/ovh/ovh.go b/ovh/ovh.go index 9c47e43..6ad609f 100644 --- a/ovh/ovh.go +++ b/ovh/ovh.go @@ -397,24 +397,36 @@ func (c *Client) CallAPIWithContext(ctx context.Context, method, path string, re // UnmarshalResponse checks the response and unmarshals it into the response // type if needed Helper function, called from CallAPI func (c *Client) UnmarshalResponse(response *http.Response, resType interface{}) error { - // Read all the response body - defer response.Body.Close() - body, err := ioutil.ReadAll(response.Body) - if err != nil { - return err - } // < 200 && >= 300 : API error if response.StatusCode < http.StatusOK || response.StatusCode >= http.StatusMultipleChoices { + + // Read all the response body + defer response.Body.Close() + errBody, err := ioutil.ReadAll(response.Body) + if err != nil { + // If we cannot read the body, send back the status code as an error + apiError := &APIError{Code: response.StatusCode} + return apiError + } + + // if we have a body for the error - create API error from the body apiError := &APIError{Code: response.StatusCode} - if err = json.Unmarshal(body, apiError); err != nil { - apiError.Message = string(body) + if err = json.Unmarshal(errBody, apiError); err != nil { + apiError.Message = string(errBody) } apiError.QueryID = response.Header.Get("X-Ovh-QueryID") return apiError } + body, err := ioutil.ReadAll(response.Body) + if err != nil { + // If we cannot read the body, send back the status code as an error + apiError := &APIError{Code: response.StatusCode} + return apiError + } + // Nothing to unmarshal if len(body) == 0 || resType == nil { return nil @@ -424,3 +436,4 @@ func (c *Client) UnmarshalResponse(response *http.Response, resType interface{}) d.UseNumber() return d.Decode(&resType) } + diff --git a/ovh/ovh_test.go b/ovh/ovh_test.go index 66bde9e..f27f163 100644 --- a/ovh/ovh_test.go +++ b/ovh/ovh_test.go @@ -325,11 +325,12 @@ func TestGetResponse(t *testing.T) { }, "Can parse a API error") td.Cmp(t, apiInt, 0) - // Error: body read error + // Error: Cannot read the error body err = client.UnmarshalResponse(&http.Response{ - Body: ErrorReadCloser{}, + StatusCode: 400, + Body: ErrorReadCloser{}, }, nil) - td.CmpString(t, err, "ErrorReader") + td.Cmp(t, err, &APIError{Code: 400}) // Error: HTTP Error + broken json err = client.UnmarshalResponse(&http.Response{