github.com/catandhorse/git-lfs@v2.5.2+incompatible/lfsapi/errors.go (about) 1 package lfsapi 2 3 import ( 4 "fmt" 5 "net/http" 6 "strings" 7 8 "github.com/git-lfs/git-lfs/errors" 9 ) 10 11 type httpError interface { 12 Error() string 13 HTTPResponse() *http.Response 14 } 15 16 func IsHTTP(err error) (*http.Response, bool) { 17 if httpErr, ok := err.(httpError); ok { 18 return httpErr.HTTPResponse(), true 19 } 20 return nil, false 21 } 22 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 28 } 29 30 func (e *ClientError) HTTPResponse() *http.Response { 31 return e.response 32 } 33 34 func (e *ClientError) Error() string { 35 return e.Message 36 } 37 38 func (c *Client) handleResponse(res *http.Response) error { 39 if res.StatusCode < 400 { 40 return nil 41 } 42 43 cliErr := &ClientError{response: res} 44 err := DecodeJSON(res, cliErr) 45 if IsDecodeTypeError(err) { 46 err = nil 47 } 48 49 if err == nil { 50 if len(cliErr.Message) == 0 { 51 err = defaultError(res) 52 } else { 53 err = cliErr 54 } 55 } 56 57 if res.StatusCode == 401 { 58 return errors.NewAuthError(err) 59 } 60 61 if res.StatusCode == 422 { 62 return errors.NewUnprocessableEntityError(err) 63 } 64 65 if res.StatusCode > 499 && res.StatusCode != 501 && res.StatusCode != 507 && res.StatusCode != 509 { 66 return errors.NewFatalError(err) 67 } 68 69 return err 70 } 71 72 type statusCodeError struct { 73 response *http.Response 74 } 75 76 func NewStatusCodeError(res *http.Response) error { 77 return &statusCodeError{response: res} 78 } 79 80 func (e *statusCodeError) Error() string { 81 req := e.response.Request 82 return fmt.Sprintf("Invalid HTTP status for %s %s: %d", 83 req.Method, 84 strings.SplitN(req.URL.String(), "?", 2)[0], 85 e.response.StatusCode, 86 ) 87 } 88 89 func (e *statusCodeError) HTTPResponse() *http.Response { 90 return e.response 91 } 92 93 var ( 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", 105 } 106 ) 107 108 func defaultError(res *http.Response) error { 109 var msgFmt string 110 111 if f, ok := defaultErrors[res.StatusCode]; ok { 112 msgFmt = f 113 } else if res.StatusCode < 500 { 114 msgFmt = defaultErrors[400] + fmt.Sprintf(" from HTTP %d", res.StatusCode) 115 } else { 116 msgFmt = defaultErrors[500] + fmt.Sprintf(" from HTTP %d", res.StatusCode) 117 } 118 119 return errors.Errorf(msgFmt, res.Request.URL) 120 }