response.go raw
1 package api
2
3 import (
4 "encoding/json"
5 "strings"
6 )
7
8 type ResponseCommon struct {
9 RequestID string `read:"request_id"`
10 }
11
12 type RawResponse struct {
13 ResponseCommon `read:",inline"`
14 Result json.RawMessage `read:"result,omitempty"`
15 Results json.RawMessage `read:"results,omitempty"`
16 }
17
18 const (
19 ErrorTypeParamaterError string = "ParameterError"
20 ErrorTypeNotFound string = "NotFound"
21 ErrorTypeTooManyRequests string = "TooManyRequests"
22 ErrorTypeSystemError string = "SystemError"
23 ErrorTypeGatewayTimeout string = "GatewayTimeout"
24 )
25
26 type BadResponse struct {
27 ResponseCommon `read:",inline"`
28 StatusCode int `read:"-"`
29 ErrorType string `read:"error_type"`
30 ErrorMessage string `read:"error_message"`
31 ErrorDetails ErrorDetails `read:"error_details"`
32 }
33
34 func (r *BadResponse) Error() string {
35 if r.ErrorType == ErrorTypeParamaterError {
36 if r.IsAuthError() {
37 return "Auth error"
38 }
39 }
40 errorDetail := ""
41 if len(r.ErrorDetails) > 0 {
42 errorDetail = " Detail: " + r.ErrorDetails.Error()
43 }
44 return "ErrorType: " + r.ErrorType + " Message: " + r.ErrorMessage + errorDetail
45 }
46
47 func (r *BadResponse) IsStatusCode(code int) bool {
48 return r.StatusCode == code
49 }
50
51 func (r *BadResponse) IsErrType(name string) bool {
52 return r.ErrorType == name
53 }
54
55 func (r *BadResponse) IsErrMsg(msg string) bool {
56 return r.ErrorMessage == msg
57 }
58
59 func (r *BadResponse) IsErrorCode(code string) (bool, string) {
60 for _, errDetail := range r.ErrorDetails {
61 if errDetail.Code == code {
62 return true, errDetail.Attribute
63 }
64 }
65 return false, ""
66 }
67
68 func (r *BadResponse) IsErrorCodeAttribute(code string, attribute string) bool {
69 for _, errDetail := range r.ErrorDetails {
70 if errDetail.Code == code && errDetail.Attribute == attribute {
71 return true
72 }
73 }
74 return false
75 }
76
77 func (r *BadResponse) IsAuthError() bool {
78 if r.IsStatusCode(400) &&
79 r.IsErrType(ErrorTypeParamaterError) &&
80 r.IsErrorCodeAttribute("invalid", "access_token") {
81 return true
82 }
83 return false
84 }
85
86 func (r *BadResponse) IsRequestFormatError() bool {
87 if r.IsStatusCode(400) &&
88 r.IsErrType(ErrorTypeParamaterError) &&
89 r.IsErrMsg("JSON parse error occurred.") {
90 return true
91 }
92 return false
93 }
94
95 func (r *BadResponse) IsParameterError() bool {
96 if r.IsStatusCode(400) &&
97 r.IsErrType(ErrorTypeParamaterError) &&
98 !r.IsAuthError() &&
99 !r.IsRequestFormatError() {
100 return true
101 }
102
103 return false
104 }
105
106 func (r *BadResponse) IsNotFound() bool {
107 return r.IsStatusCode(404)
108 }
109
110 func (r *BadResponse) IsTooManyRequests() bool {
111 return r.IsStatusCode(429)
112 }
113
114 func (r *BadResponse) IsSystemError() bool {
115 return r.IsStatusCode(500)
116 }
117
118 func (r *BadResponse) IsGatewayTimeout() bool {
119 return r.IsStatusCode(504)
120 }
121
122 func (r *BadResponse) IsInvalidSchema() bool {
123 return r.IsParameterError() && r.IsErrorCodeAttribute("invalid", "schema")
124 }
125
126 type ErrorDetails []ErrorDetail
127
128 func (e ErrorDetails) Error() string {
129 res := []string{}
130 for _, detail := range e {
131 res = append(res, detail.Error())
132 }
133 return strings.Join(res, ", ")
134 }
135
136 type ErrorDetail struct {
137 Code string `read:"code"`
138 Attribute string `read:"attribute"`
139 }
140
141 func (e ErrorDetail) Error() string {
142 return e.Code + "=" + e.Attribute
143 }
144
145 type Count struct {
146 Count int32 `read:"count" json:"-"`
147 }
148
149 func (c *Count) SetCount(v int32) { c.Count = v }
150 func (c *Count) GetCount() int32 { return c.Count }
151
152 type AsyncResponse struct {
153 ResponseCommon `read:",inline"`
154 JobsURL string `read:"jobs_url"`
155 }
156