error.go raw
1 package dara
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "net/http"
8 "reflect"
9 "strconv"
10 "github.com/alibabacloud-go/tea/tea"
11 )
12
13 type BaseError interface {
14 error
15 GetName() *string
16 GetCode() *string
17 }
18
19 type ResponseError interface {
20 BaseError
21 GetRetryAfter() *int64
22 GetStatusCode() *int
23 GetAccessDeniedDetail() map[string]interface{}
24 GetDescription() *string
25 GetData() map[string]interface{}
26 }
27
28 // SDKError struct is used save error code and message
29 type SDKError struct {
30 BaseError
31 Code *string
32 Name *string
33 StatusCode *int
34 Message *string
35 Data *string
36 Stack *string
37 errMsg *string
38 Description *string
39 AccessDeniedDetail map[string]interface{}
40 }
41
42 // CastError is used for cast type fails
43 type CastError struct {
44 Message *string
45 }
46
47 func TeaSDKError(err error) error {
48 if(err == nil) {
49 return nil
50 }
51
52 if te, ok := err.(*SDKError); ok {
53 return tea.NewSDKError(map[string]interface{}{
54 "code": StringValue(te.Code),
55 "statusCode": IntValue(te.StatusCode),
56 "message": StringValue(te.Message),
57 "data": te.Data,
58 "description": StringValue(te.Description),
59 "accessDeniedDetail": te.AccessDeniedDetail,
60 })
61 }
62
63 if respErr, ok := err.(ResponseError); ok {
64 return tea.NewSDKError(map[string]interface{}{
65 "code": StringValue(respErr.GetCode()),
66 "statusCode": IntValue(respErr.GetStatusCode()),
67 "message": respErr.Error(),
68 "description": StringValue(respErr.GetDescription()),
69 "data": respErr.GetData(),
70 "accessDeniedDetail": respErr.GetAccessDeniedDetail(),
71 })
72 }
73
74 if baseErr, ok := err.(BaseError); ok {
75 return tea.NewSDKError(map[string]interface{}{
76 "code": StringValue(baseErr.GetCode()),
77 "message": baseErr.Error(),
78 })
79 }
80
81 return err
82 }
83
84 // NewSDKError is used for shortly create SDKError object
85 func NewSDKError(obj map[string]interface{}) *SDKError {
86 err := &SDKError{}
87 err.Name = String("BaseError")
88 if val, ok := obj["code"].(int); ok {
89 err.Code = String(strconv.Itoa(val))
90 } else if val, ok := obj["code"].(string); ok {
91 err.Code = String(val)
92 }
93
94 if obj["message"] != nil {
95 err.Message = String(obj["message"].(string))
96 }
97
98 if obj["name"] != nil {
99
100 }
101
102 if obj["description"] != nil {
103 err.Description = String(obj["description"].(string))
104 }
105 if detail := obj["accessDeniedDetail"]; detail != nil {
106 r := reflect.ValueOf(detail)
107 if r.Kind().String() == "map" {
108 res := make(map[string]interface{})
109 tmp := r.MapKeys()
110 for _, key := range tmp {
111 res[key.String()] = r.MapIndex(key).Interface()
112 }
113 err.AccessDeniedDetail = res
114 }
115 }
116 if data := obj["data"]; data != nil {
117 r := reflect.ValueOf(data)
118 if r.Kind().String() == "map" {
119 res := make(map[string]interface{})
120 tmp := r.MapKeys()
121 for _, key := range tmp {
122 res[key.String()] = r.MapIndex(key).Interface()
123 }
124 if statusCode := res["statusCode"]; statusCode != nil {
125 if code, ok := statusCode.(int); ok {
126 err.StatusCode = Int(code)
127 } else if tmp, ok := statusCode.(string); ok {
128 code, err_ := strconv.Atoi(tmp)
129 if err_ == nil {
130 err.StatusCode = Int(code)
131 }
132 } else if code, ok := statusCode.(*int); ok {
133 err.StatusCode = code
134 }
135 }
136 }
137 byt := bytes.NewBuffer([]byte{})
138 jsonEncoder := json.NewEncoder(byt)
139 jsonEncoder.SetEscapeHTML(false)
140 jsonEncoder.Encode(data)
141 err.Data = String(string(bytes.TrimSpace(byt.Bytes())))
142 }
143
144 if statusCode, ok := obj["statusCode"].(int); ok {
145 err.StatusCode = Int(statusCode)
146 } else if status, ok := obj["statusCode"].(string); ok {
147 statusCode, err_ := strconv.Atoi(status)
148 if err_ == nil {
149 err.StatusCode = Int(statusCode)
150 }
151 }
152
153 return err
154 }
155
156 func (err *SDKError) ErrorName() *string {
157 return err.Name
158 }
159
160 func (err *SDKError) ErrorMessage() *string {
161 return err.Message
162 }
163
164 func (err *SDKError) GetCode() *string {
165 return err.Code
166 }
167
168 // Set ErrMsg by msg
169 func (err *SDKError) SetErrMsg(msg string) {
170 err.errMsg = String(msg)
171 }
172
173 func (err *SDKError) Error() string {
174 if err.errMsg == nil {
175 str := fmt.Sprintf("SDKError:\n StatusCode: %d\n Code: %s\n Message: %s\n Data: %s\n",
176 IntValue(err.StatusCode), StringValue(err.Code), StringValue(err.Message), StringValue(err.Data))
177 err.SetErrMsg(str)
178 }
179 return StringValue(err.errMsg)
180 }
181
182 // Return message of CastError
183 func (err *CastError) Error() string {
184 return StringValue(err.Message)
185 }
186
187 func Retryable(err error) *bool {
188 if err == nil {
189 return Bool(false)
190 }
191 if realErr, ok := err.(*SDKError); ok {
192 if realErr.StatusCode == nil {
193 return Bool(false)
194 }
195 code := IntValue(realErr.StatusCode)
196 return Bool(code >= http.StatusInternalServerError)
197 }
198 return Bool(true)
199 }
200
201 // NewCastError is used for cast type fails
202 func NewCastError(message *string) (err error) {
203 return &CastError{
204 Message: message,
205 }
206 }
207