8 "github.com/git-lfs/git-lfs/errors"
11 type httpError interface {
13 HTTPResponse() *http.Response
16 func IsHTTP(err error) (*http.Response, bool) {
17 if httpErr, ok := err.(httpError); ok {
18 return httpErr.HTTPResponse(), true
23 type ClientError struct {
24 Message string `json:"message"`
25 DocumentationUrl string `json:"documentation_url,omitempty"`
26 RequestId string `json:"request_id,omitempty"`
27 response *http.Response
30 func (e *ClientError) HTTPResponse() *http.Response {
34 func (e *ClientError) Error() string {
38 func (c *Client) handleResponse(res *http.Response) error {
39 if res.StatusCode < 400 {
43 cliErr := &ClientError{response: res}
44 err := DecodeJSON(res, cliErr)
45 if IsDecodeTypeError(err) {
50 if len(cliErr.Message) == 0 {
51 err = defaultError(res)
57 if res.StatusCode == 401 {
58 return errors.NewAuthError(err)
61 if res.StatusCode == 422 {
62 return errors.NewUnprocessableEntityError(err)
65 if res.StatusCode > 499 && res.StatusCode != 501 && res.StatusCode != 507 && res.StatusCode != 509 {
66 return errors.NewFatalError(err)
72 type statusCodeError struct {
73 response *http.Response
76 func NewStatusCodeError(res *http.Response) error {
77 return &statusCodeError{response: res}
80 func (e *statusCodeError) Error() string {
81 req := e.response.Request
82 return fmt.Sprintf("Invalid HTTP status for %s %s: %d",
84 strings.SplitN(req.URL.String(), "?", 2)[0],
85 e.response.StatusCode,
89 func (e *statusCodeError) HTTPResponse() *http.Response {
94 defaultErrors = map[int]string{
95 400: "Client error: %s",
96 401: "Authorization error: %s\nCheck that you have proper access to the repository",
97 403: "Authorization error: %s\nCheck that you have proper access to the repository",
98 404: "Repository or object not found: %s\nCheck that it exists and that you have proper access to it",
99 422: "Unprocessable entity: %s",
100 429: "Rate limit exceeded: %s",
101 500: "Server error: %s",
102 501: "Not Implemented: %s",
103 507: "Insufficient server storage: %s",
104 509: "Bandwidth limit exceeded: %s",
108 func defaultError(res *http.Response) error {
111 if f, ok := defaultErrors[res.StatusCode]; ok {
113 } else if res.StatusCode < 500 {
114 msgFmt = defaultErrors[400] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
116 msgFmt = defaultErrors[500] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
119 return errors.Errorf(msgFmt, res.Request.URL)