github.com/alibabacloud-go/tea@v1.3.10/dara/error.go (about) 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 }