github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/util/err.go (about) 1 package util 2 3 import ( 4 "regexp" 5 "runtime" 6 "strconv" 7 ) 8 9 const ( 10 EcMin TErrCode = iota + 60000 11 EcNil 12 EcRecover 13 EcWrongType 14 EcBusy 15 EcNotEnough 16 EcNoAuth 17 EcTimeout 18 EcClosed 19 EcOpened 20 EcEmpty 21 EcBadHead 22 EcBadPacket 23 EcExist 24 EcNotExist 25 EcMarshallErr 26 EcUnmarshallErr 27 EcIllegalOp 28 EcIllegalConn 29 EcTooManyConn 30 EcParamsErr 31 EcParseErr 32 EcIo 33 EcOutOfRange 34 EcTooLong 35 EcTooMuch 36 EcLengthErr 37 EcNotExistAgent 38 EcSendErr 39 EcReceiveErr 40 EcAcceptErr 41 EcConnectErr 42 EcListenErr 43 EcAddrErr 44 EcUnavailable 45 EcNotImplement 46 EcType 47 EcWriteFail 48 EcFail 49 EcTooSlow 50 EcServiceErr 51 EcDbErr 52 EcRedisErr 53 EcEtcdErr 54 ) 55 56 var ( 57 _ErrCodeToString = map[TErrCode]string{ 58 EcNil: "object_nil", 59 EcRecover: "recover", 60 EcWrongType: "wrong_type", 61 EcBusy: "busy", 62 EcNotEnough: "not_enough", 63 EcNoAuth: "no_auth", 64 EcTimeout: "timeout", 65 EcClosed: "closed", 66 EcOpened: "opened", 67 EcEmpty: "empty", 68 EcBadHead: "bad_head", 69 EcBadPacket: "bad_packet", 70 EcExist: "exist", 71 EcNotExist: "not_exist", 72 EcMarshallErr: "marshall_error", 73 EcUnmarshallErr: "unmarshall_error", 74 EcIllegalOp: "illegal_operation", 75 EcIllegalConn: "illegal_conn", 76 EcTooManyConn: "too_many_conn", 77 EcParamsErr: "args_error", 78 EcParseErr: "parse_error", 79 EcIo: "io_error", 80 EcOutOfRange: "out_of_range", 81 EcTooLong: "too_long", 82 EcTooMuch: "too_much", 83 EcLengthErr: "length_wrong", 84 EcNotExistAgent: "not_exist_agent", 85 EcSendErr: "send_error", 86 EcReceiveErr: "receive_error", 87 EcAcceptErr: "accept_error", 88 EcConnectErr: "connect_error", 89 EcListenErr: "listen_error", 90 EcServiceErr: "service_error", 91 EcDbErr: "database_error", 92 EcRedisErr: "redis_wrong", 93 EcEtcdErr: "etcd_wrong", 94 EcAddrErr: "get_addr_error", 95 EcUnavailable: "unavailable", 96 EcNotImplement: "not_implement", 97 EcType: "err_type", 98 EcWriteFail: "write_fail", 99 EcFail: "fail_code", 100 EcTooSlow: "too_slow", 101 } 102 ) 103 104 func SetErrCodeToStr(ec TErrCode, str string) { 105 _ErrCodeToString[ec] = str 106 } 107 108 func ErrCodeToStr(ec TErrCode) string { 109 str, ok := _ErrCodeToString[ec] 110 if ok { 111 return str 112 } 113 return strconv.FormatInt(int64(ec), 10) 114 } 115 116 func WrapErr(code TErrCode, e error) *Err { 117 if e == nil { 118 return &Err{code: code, stack: GetStack(3)} 119 } 120 return &Err{code: code, stack: GetStack(3), params: M{"error": e.Error()}} 121 } 122 123 func NewErr(code TErrCode, params M) *Err { 124 return &Err{code: code, stack: GetStack(3), params: params} 125 } 126 127 func NewNoStackErr(code TErrCode, params M) *Err { 128 return &Err{code: code, stack: nil, params: params} 129 } 130 131 func NewErrWithStack(code TErrCode, stack []byte, params M) *Err { 132 return &Err{code: code, stack: stack, params: params} 133 } 134 135 type Err struct { 136 code TErrCode 137 stack []byte 138 params M 139 } 140 141 func (e *Err) Code() TErrCode { 142 return e.code 143 } 144 145 func (e *Err) ToBytes() []byte { 146 if e.params == nil { 147 e.params = map[string]any{} 148 } 149 e.params["code"] = e.code 150 if e.stack != nil { 151 e.params["stack"] = BytesToStr(e.stack) 152 } 153 bytes, _ := JsonMarshal(e.params) 154 return bytes 155 } 156 157 func (e *Err) Error() string { 158 err, ok := e.params["error"] 159 if ok { 160 return err.(string) 161 } 162 return BytesToStr(e.ToBytes()) 163 } 164 165 func (e *Err) Params() M { 166 return e.params 167 } 168 169 func (e *Err) Stack() []byte { 170 return e.stack 171 } 172 173 func (e *Err) IsNoStack() bool { 174 return e.stack == nil 175 } 176 177 func (e *Err) AddParam(k string, v any) { 178 if e.params == nil { 179 e.params = map[string]any{} 180 } 181 e.params[k] = v 182 } 183 184 func (e *Err) GetParam(k string) (v any, ok bool) { 185 if e.params == nil { 186 return nil, false 187 } 188 v, ok = e.params[k] 189 return 190 } 191 192 func (e *Err) AddParams(params M) { 193 if e.params == nil { 194 e.params = map[string]any{} 195 } 196 for k, v := range params { 197 e.params[k] = v 198 } 199 } 200 201 func (e *Err) UpdateParam(k string, action AnyBoolToAnyBool) { 202 if e.params == nil { 203 e.params = map[string]any{} 204 } 205 ov, ok := e.params[k] 206 v, ok := action(ov, ok) 207 if ok { 208 e.params[k] = v 209 } else { 210 delete(e.params, k) 211 } 212 } 213 214 func (e *Err) String() string { 215 return ErrCodeToStr(e.code) 216 } 217 218 func GetStack(skip int) []byte { 219 const depth = 16 220 var rpc [depth]uintptr 221 n := runtime.Callers(skip, rpc[:]) 222 if n < 1 { 223 return nil 224 } 225 frames := runtime.CallersFrames(rpc[:]) 226 227 var buffer ByteBuffer 228 buffer.InitCap(256) 229 for i := 0; i < StackMaxDeep; i++ { 230 frame, ok := frames.Next() 231 if !ok { 232 break 233 } 234 buffer.WUint8('\n') 235 buffer.WUint8('\t') 236 buffer.WStringNoLen(LogTrim(frame.File)) 237 buffer.WUint8(':') 238 buffer.WStringNoLen(strconv.Itoa(frame.Line)) 239 } 240 return buffer.All() 241 } 242 243 var ( 244 StackMaxDeep = 8 245 LogPrefix = ".." 246 LogReg = regexp.MustCompile(`(\/.+\.(com)|(org))|(\/.+go\d{1}\.\d{1,2}.\d{1,2}|/src)`) 247 ) 248 249 func LogTrim(file string) string { 250 s := LogReg.FindStringIndex(file) 251 if len(s) > 0 { 252 return LogPrefix + file[s[1]:] 253 } 254 return file 255 }