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