Skip to content

Commit

Permalink
Merge pull request #10 from omc/dx/gracefully-return-empty-http-err-r…
Browse files Browse the repository at this point in the history
…esponse

Suppress unmarshal errors in the unexpected event that API doesn't return an error descriptor in the body
  • Loading branch information
momer authored May 3, 2024
2 parents 96850a6 + db06a85 commit cac4273
Showing 1 changed file with 23 additions and 11 deletions.
34 changes: 23 additions & 11 deletions bonsai/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ type Response struct {
PaginatedResponse `json:"pagination"`
}

func (r *Response) isJSON() bool {
return r.Header.Get("Content-Type") == HTTPContentTypeJSON
}

// WithHTTPResponse assigns an *http.Response to a *Response item
// and reads its response body into the *Response.
func (r *Response) WithHTTPResponse(httpResp *http.Response) error {
Expand Down Expand Up @@ -451,24 +455,32 @@ func (c *Client) doRequest(ctx context.Context, req *http.Request, reqBuf *bytes
return resp, fmt.Errorf("setting http response: %w", err)
}

// Extract the pagination details
if httpResp.Header.Get("Content-Type") == HTTPContentTypeJSON {
err = json.Unmarshal(resp.BodyBuf.Bytes(), &resp)
if err != nil {
return resp, fmt.Errorf("error unmarshaling response body for pagination: %w", err)
}
}

// All error reposes should come with a JSON response per the Error handling
// section @ https://bonsai.io/docs/introduction-to-the-api.
//
// That said, in the scenario that an error *isn't* returned as a JSON body
// response, it would be jarring to receive a message about an internal
// unmarshaling attempt, rather than to receive the HTTP Status Error
if resp.StatusCode >= http.StatusBadRequest {
respErr := ResponseError{}
if err = json.Unmarshal(resp.BodyBuf.Bytes(), &respErr); err != nil {
return resp, fmt.Errorf("unmarshaling error response: %w", err)
respErr := ResponseError{Status: resp.StatusCode}

if ok := resp.isJSON(); ok {
// Suppress unmarshaling errors in the event that the response didn't
// contain a message.
_ = json.Unmarshal(resp.BodyBuf.Bytes(), &respErr)
}

return resp, respErr
}

// Extract the pagination details
if resp.isJSON() {
err = json.Unmarshal(resp.BodyBuf.Bytes(), &resp)
if err != nil {
return resp, fmt.Errorf("error unmarshaling response body for pagination: %w", err)
}
}

return resp, err
}

Expand Down

0 comments on commit cac4273

Please sign in to comment.