func ParseJSON(res *http.Response, data interface{}) error { body, err := ioutil.ReadAll(res.Body) if err != nil { return errgo.Newf("fail to read body of request %v, %v", res.Request, err) } debug.Println(string(body)) err = json.Unmarshal(body, data) if err != nil { return errgo.Newf("fail to parse JSON of request %v, %v", res.Request, err) } return nil }
func NewRequestFailedError(res *http.Response, req *APIRequest) error { debug.Println("APIRequest Error:", res.StatusCode, req.Method, req.Endpoint) defer res.Body.Close() switch res.StatusCode { case 400: var badRequestError BadRequestError err := ParseJSON(res, &badRequestError) if err != nil { return errgo.Mask(err, errgo.Any) } return &RequestFailedError{res.StatusCode, badRequestError, req} case 401: return &RequestFailedError{res.StatusCode, errgo.New("unauthorized - you are not authorized to do this operation"), req} case 402: var paymentRequiredErr PaymentRequiredError err := ParseJSON(res, &paymentRequiredErr) if err != nil { return errgo.Mask(err, errgo.Any) } return &RequestFailedError{res.StatusCode, paymentRequiredErr, req} case 404: var notFoundErr NotFoundError err := ParseJSON(res, ¬FoundErr) if err != nil { return errgo.Mask(err, errgo.Any) } return &RequestFailedError{res.StatusCode, notFoundErr, req} case 422: var unprocessableError UnprocessableEntity err := ParseJSON(res, &unprocessableError) if err != nil { return errgo.Mask(err, errgo.Any) } return &RequestFailedError{res.StatusCode, unprocessableError, req} case 500: return &RequestFailedError{res.StatusCode, errgo.New("server internal error - our team has been notified"), req} case 503: return &RequestFailedError{res.StatusCode, fmt.Errorf("upstream provider returned an error, please retry later"), req} default: return &RequestFailedError{res.StatusCode, fmt.Errorf("invalid status from server: %v", res.Status), req} } }