gitee.com/h79/goutils@v1.22.10/common/result/result.go (about) 1 package result 2 3 import ( 4 "context" 5 "fmt" 6 "go.uber.org/zap" 7 "reflect" 8 ) 9 10 var DefaultOk = ErrOk 11 12 var Type = reflect.TypeOf((*Object)(nil)).Elem() 13 14 type Object interface { 15 ToResult() Result 16 } 17 18 type Result struct { 19 Errno int32 `json:"code"` //业务错误码=0,表示正确,其它失败 20 SubCode int32 `json:"subCode"` //业务子码 21 Desc string `json:"desc"` //错误信息 22 Msg string `json:"msg"` //提供给界面提示之类 23 } 24 25 func New(code int32, err string) error { 26 return Error(code, err) 27 } 28 29 func Case(a any) (Result, bool) { 30 val := reflect.ValueOf(a) 31 if val.CanInterface() && val.Type().Implements(Type) { 32 var v = val.Interface().(Object) 33 return v.ToResult(), true 34 } 35 return Result{}, false 36 } 37 38 func Succeed() Result { 39 return Result{Errno: DefaultOk, Desc: ""} 40 } 41 42 func Error(code int32, err string) Result { 43 return Result{Errno: code, Desc: err, Msg: err} 44 } 45 46 func ErrCode(code int32) Result { 47 return Result{Errno: code} 48 } 49 50 func Errorf(code int32, f string, arg ...interface{}) Result { 51 desc := fmt.Sprintf(f, arg...) 52 return Result{Errno: code, Desc: desc, Msg: desc} 53 } 54 55 func WithErr(err error) Result { 56 res := Result{} 57 return res.WithError(err) 58 } 59 60 func IsOK(code int32) bool { 61 return code == DefaultOk || code == Success 62 } 63 64 func (r Result) Is(err error) bool { 65 if err == nil { 66 return false 67 } 68 if res, ok := err.(*Result); ok { 69 return res.Errno == r.Errno && res.SubCode == r.SubCode 70 } 71 if res, ok := err.(Result); ok { 72 return res.Errno == r.Errno && res.SubCode == r.SubCode 73 } 74 return false 75 } 76 77 // error interface 78 func (r Result) Error() string { 79 if r.Msg != "" { 80 return r.Msg 81 } 82 return r.Desc 83 } 84 85 func (r Result) Ok() bool { 86 return IsOK(r.Errno) 87 } 88 89 func (r Result) NotFound() bool { 90 return r.Equal(ErrNotFound) 91 } 92 93 // NonFound 94 // 不是NOT FOUND的错误 95 func (r Result) NonFound() bool { 96 return !r.Equal(ErrOk) && !r.Equal(ErrNotFound) && !r.Equal(Success) 97 } 98 99 func (r Result) Equal(code int32) bool { 100 return code == r.Errno 101 } 102 103 func (r Result) WithSubCode(code int32) Result { 104 r.SubCode = code 105 return r 106 } 107 108 func (r Result) WithMsg(msg string) Result { 109 r.Msg = msg 110 return r 111 } 112 113 func (r Result) AppendMsg(msg string) Result { 114 r.Msg += msg 115 return r 116 } 117 118 func (r Result) AppendDesc(desc string) Result { 119 r.Desc += desc 120 return r 121 } 122 123 func (r Result) WithError(err error) Result { 124 if err == nil { 125 return Succeed() 126 } 127 if res, ok := err.(*Result); ok { 128 return (*res).Exception(r.Errno) 129 } 130 if res, ok := err.(Result); ok { 131 return res.Exception(r.Errno) 132 } 133 if i18n, ok := err.(I18n); ok { 134 r.Msg = i18n.Content 135 return r.Exception(ErrException) 136 } 137 if i18n, ok := err.(*I18n); ok { 138 r.Msg = i18n.Content 139 return r.Exception(ErrException) 140 } 141 if res, ok := Case(err); ok { 142 return res.Exception(r.Errno) 143 } 144 r.Desc = err.Error() 145 r.Msg = r.Desc 146 return r.Exception(ErrException) 147 } 148 149 func (r Result) Exception(code int32) Result { 150 if r.Ok() { 151 if code == 0 { 152 code = ErrException 153 } 154 r.Errno = code 155 } 156 return r 157 } 158 159 func (r Result) Log() Result { 160 if !r.Ok() { 161 zap.L().WithOptions(zap.AddCallerSkip(1)).Error("Result", 162 zap.Int32("errno", r.Errno), 163 zap.Int32("subCode", r.SubCode), 164 zap.String("msg", r.Msg), 165 zap.String("desc", r.Desc)) 166 } 167 return r 168 } 169 170 func (r Result) LogWithContext(ctx context.Context) Result { 171 if !r.Ok() { 172 zap.L().WithOptions(zap.AddCallerSkip(1)).Error("Result", 173 zap.Any("traceId", ctx.Value("traceId")), 174 zap.Int32("errno", r.Errno), 175 zap.Int32("subCode", r.SubCode), 176 zap.String("msg", r.Msg), 177 zap.String("desc", r.Desc)) 178 } 179 return r 180 } 181 182 func (r Result) LogM(model string, d interface{}) Result { 183 if !r.Ok() { 184 zap.L().WithOptions(zap.AddCallerSkip(1)).Error("Result", 185 zap.Any("data", d), 186 zap.String("model", model), 187 zap.Int32("errno", r.Errno), 188 zap.Int32("subCode", r.SubCode), 189 zap.String("msg", r.Msg), 190 zap.String("desc", r.Desc)) 191 return r.LogMWithContext(context.Background(), model, d) 192 } 193 return r 194 } 195 196 func (r Result) LogMWithContext(ctx context.Context, model string, d interface{}) Result { 197 if !r.Ok() { 198 zap.L().WithOptions(zap.AddCallerSkip(1)).Error("Result", 199 zap.Any("traceId", ctx.Value("traceId")), 200 zap.Any("data", d), 201 zap.String("model", model), 202 zap.Int32("errno", r.Errno), 203 zap.Int32("subCode", r.SubCode), 204 zap.String("msg", r.Msg), 205 zap.String("desc", r.Desc)) 206 } 207 return r 208 }