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  }