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  }