-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
error.go
85 lines (70 loc) · 1.71 KB
/
error.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package client
import (
"encoding/json"
"io"
"net/http"
"strings"
)
// APIError errors that may return from the Client.
type APIError struct {
Response *http.Response
Body json.RawMessage // may be any []byte, response body is closed at this point.
}
// Error implements the standard error type.
func (e APIError) Error() string {
var b strings.Builder
if e.Response != nil {
b.WriteString(e.Response.Request.URL.String())
b.WriteByte(':')
b.WriteByte(' ')
b.WriteString(http.StatusText(e.Response.StatusCode))
b.WriteByte(' ')
b.WriteByte('(')
b.WriteString(e.Response.Status)
b.WriteByte(')')
if len(e.Body) > 0 {
b.WriteByte(':')
b.WriteByte(' ')
b.Write(e.Body)
}
}
return b.String()
}
// ExtractError returns the response wrapped inside an APIError.
func ExtractError(resp *http.Response) APIError {
body, _ := io.ReadAll(resp.Body)
return APIError{
Response: resp,
Body: body,
}
}
// GetError reports whether the given "err" is an APIError.
func GetError(err error) (APIError, bool) {
if err == nil {
return APIError{}, false
}
apiErr, ok := err.(APIError)
if !ok {
return APIError{}, false
}
return apiErr, true
}
// DecodeError binds a json error to the "destPtr".
func DecodeError(err error, destPtr interface{}) error {
apiErr, ok := GetError(err)
if !ok {
return err
}
return json.Unmarshal(apiErr.Body, destPtr)
}
// GetErrorCode reads an error, which should be a type of APIError,
// and returns its status code.
// If the given "err" is nil or is not an APIError it returns 200,
// acting as we have no error.
func GetErrorCode(err error) int {
apiErr, ok := GetError(err)
if !ok {
return http.StatusOK
}
return apiErr.Response.StatusCode
}