errors.go raw

   1  package v3
   2  
   3  import (
   4  	"encoding/json"
   5  	"errors"
   6  	"fmt"
   7  	"io"
   8  	"net/http"
   9  )
  10  
  11  var (
  12  	ErrBadRequest                    = errors.New(http.StatusText(http.StatusBadRequest))
  13  	ErrUnauthorized                  = errors.New(http.StatusText(http.StatusUnauthorized))
  14  	ErrPaymentRequired               = errors.New(http.StatusText(http.StatusPaymentRequired))
  15  	ErrForbidden                     = errors.New(http.StatusText(http.StatusForbidden))
  16  	ErrNotFound                      = errors.New(http.StatusText(http.StatusNotFound))
  17  	ErrMethodNotAllowed              = errors.New(http.StatusText(http.StatusMethodNotAllowed))
  18  	ErrNotAcceptable                 = errors.New(http.StatusText(http.StatusNotAcceptable))
  19  	ErrProxyAuthRequired             = errors.New(http.StatusText(http.StatusProxyAuthRequired))
  20  	ErrRequestTimeout                = errors.New(http.StatusText(http.StatusRequestTimeout))
  21  	ErrConflict                      = errors.New(http.StatusText(http.StatusConflict))
  22  	ErrGone                          = errors.New(http.StatusText(http.StatusGone))
  23  	ErrLengthRequired                = errors.New(http.StatusText(http.StatusLengthRequired))
  24  	ErrPreconditionFailed            = errors.New(http.StatusText(http.StatusPreconditionFailed))
  25  	ErrRequestEntityTooLarge         = errors.New(http.StatusText(http.StatusRequestEntityTooLarge))
  26  	ErrRequestURITooLong             = errors.New(http.StatusText(http.StatusRequestURITooLong))
  27  	ErrUnsupportedMediaType          = errors.New(http.StatusText(http.StatusUnsupportedMediaType))
  28  	ErrRequestedRangeNotSatisfiable  = errors.New(http.StatusText(http.StatusRequestedRangeNotSatisfiable))
  29  	ErrExpectationFailed             = errors.New(http.StatusText(http.StatusExpectationFailed))
  30  	ErrTeapot                        = errors.New(http.StatusText(http.StatusTeapot))
  31  	ErrMisdirectedRequest            = errors.New(http.StatusText(http.StatusMisdirectedRequest))
  32  	ErrUnprocessableEntity           = errors.New(http.StatusText(http.StatusUnprocessableEntity))
  33  	ErrLocked                        = errors.New(http.StatusText(http.StatusLocked))
  34  	ErrFailedDependency              = errors.New(http.StatusText(http.StatusFailedDependency))
  35  	ErrTooEarly                      = errors.New(http.StatusText(http.StatusTooEarly))
  36  	ErrUpgradeRequired               = errors.New(http.StatusText(http.StatusUpgradeRequired))
  37  	ErrPreconditionRequired          = errors.New(http.StatusText(http.StatusPreconditionRequired))
  38  	ErrTooManyRequests               = errors.New(http.StatusText(http.StatusTooManyRequests))
  39  	ErrRequestHeaderFieldsTooLarge   = errors.New(http.StatusText(http.StatusRequestHeaderFieldsTooLarge))
  40  	ErrUnavailableForLegalReasons    = errors.New(http.StatusText(http.StatusUnavailableForLegalReasons))
  41  	ErrInternalServerError           = errors.New(http.StatusText(http.StatusInternalServerError))
  42  	ErrNotImplemented                = errors.New(http.StatusText(http.StatusNotImplemented))
  43  	ErrBadGateway                    = errors.New(http.StatusText(http.StatusBadGateway))
  44  	ErrServiceUnavailable            = errors.New(http.StatusText(http.StatusServiceUnavailable))
  45  	ErrGatewayTimeout                = errors.New(http.StatusText(http.StatusGatewayTimeout))
  46  	ErrHTTPVersionNotSupported       = errors.New(http.StatusText(http.StatusHTTPVersionNotSupported))
  47  	ErrVariantAlsoNegotiates         = errors.New(http.StatusText(http.StatusVariantAlsoNegotiates))
  48  	ErrInsufficientStorage           = errors.New(http.StatusText(http.StatusInsufficientStorage))
  49  	ErrLoopDetected                  = errors.New(http.StatusText(http.StatusLoopDetected))
  50  	ErrNotExtended                   = errors.New(http.StatusText(http.StatusNotExtended))
  51  	ErrNetworkAuthenticationRequired = errors.New(http.StatusText(http.StatusNetworkAuthenticationRequired))
  52  )
  53  
  54  var httpStatusCodeErrors = map[int]error{
  55  	http.StatusBadRequest:                    ErrBadRequest,
  56  	http.StatusUnauthorized:                  ErrUnauthorized,
  57  	http.StatusPaymentRequired:               ErrPaymentRequired,
  58  	http.StatusForbidden:                     ErrForbidden,
  59  	http.StatusNotFound:                      ErrNotFound,
  60  	http.StatusMethodNotAllowed:              ErrMethodNotAllowed,
  61  	http.StatusNotAcceptable:                 ErrNotAcceptable,
  62  	http.StatusProxyAuthRequired:             ErrProxyAuthRequired,
  63  	http.StatusRequestTimeout:                ErrRequestTimeout,
  64  	http.StatusConflict:                      ErrConflict,
  65  	http.StatusGone:                          ErrGone,
  66  	http.StatusLengthRequired:                ErrLengthRequired,
  67  	http.StatusPreconditionFailed:            ErrPreconditionFailed,
  68  	http.StatusRequestEntityTooLarge:         ErrRequestEntityTooLarge,
  69  	http.StatusRequestURITooLong:             ErrRequestURITooLong,
  70  	http.StatusUnsupportedMediaType:          ErrUnsupportedMediaType,
  71  	http.StatusRequestedRangeNotSatisfiable:  ErrRequestedRangeNotSatisfiable,
  72  	http.StatusExpectationFailed:             ErrExpectationFailed,
  73  	http.StatusTeapot:                        ErrTeapot,
  74  	http.StatusMisdirectedRequest:            ErrMisdirectedRequest,
  75  	http.StatusUnprocessableEntity:           ErrUnprocessableEntity,
  76  	http.StatusLocked:                        ErrLocked,
  77  	http.StatusFailedDependency:              ErrFailedDependency,
  78  	http.StatusTooEarly:                      ErrTooEarly,
  79  	http.StatusUpgradeRequired:               ErrUpgradeRequired,
  80  	http.StatusPreconditionRequired:          ErrPreconditionRequired,
  81  	http.StatusTooManyRequests:               ErrTooManyRequests,
  82  	http.StatusRequestHeaderFieldsTooLarge:   ErrRequestHeaderFieldsTooLarge,
  83  	http.StatusUnavailableForLegalReasons:    ErrUnavailableForLegalReasons,
  84  	http.StatusInternalServerError:           ErrInternalServerError,
  85  	http.StatusNotImplemented:                ErrNotImplemented,
  86  	http.StatusBadGateway:                    ErrBadGateway,
  87  	http.StatusServiceUnavailable:            ErrServiceUnavailable,
  88  	http.StatusGatewayTimeout:                ErrGatewayTimeout,
  89  	http.StatusHTTPVersionNotSupported:       ErrHTTPVersionNotSupported,
  90  	http.StatusVariantAlsoNegotiates:         ErrVariantAlsoNegotiates,
  91  	http.StatusInsufficientStorage:           ErrInsufficientStorage,
  92  	http.StatusLoopDetected:                  ErrLoopDetected,
  93  	http.StatusNotExtended:                   ErrNotExtended,
  94  	http.StatusNetworkAuthenticationRequired: ErrNetworkAuthenticationRequired,
  95  }
  96  
  97  func handleHTTPErrorResp(resp *http.Response) error {
  98  	if resp.StatusCode >= 400 && resp.StatusCode <= 599 {
  99  		var res struct {
 100  			Message string `json:"message"`
 101  		}
 102  
 103  		data, err := io.ReadAll(resp.Body)
 104  		if err != nil {
 105  			return fmt.Errorf("error reading response body: %s", err)
 106  		}
 107  
 108  		if json.Valid(data) {
 109  			if err = json.Unmarshal(data, &res); err != nil {
 110  				return fmt.Errorf("error unmarshaling response: %s", err)
 111  			}
 112  		} else {
 113  			res.Message = string(data)
 114  		}
 115  
 116  		err, ok := httpStatusCodeErrors[resp.StatusCode]
 117  		if ok {
 118  			return fmt.Errorf("%w: %s", err, res.Message)
 119  		}
 120  
 121  		return fmt.Errorf("unmapped HTTP error: status code %d, message: %s", resp.StatusCode, res.Message)
 122  	}
 123  
 124  	return nil
 125  }
 126