// Package exception ... // // Description : exception ... // // Author : go_developer@163.com<白茶清欢> // // Date *: 2022-06-25 21:04 package exception import ( "encoding/json" "errors" "fmt" "runtime" "strconv" "strings" ) // Exception 异常接口的具体实现 // // Author : go_developer@163.com<白茶清欢> // // Date *: 21:09 2022/6/25 type Exception struct { code any message string data map[string]any stack string } func (e *Exception) Error() string { mapData := map[string]any{ "code": e.Code(), "msg": e.Message(), "data": e.Data(), } byteData, _ := json.Marshal(mapData) return string(byteData) } func (e *Exception) GetStack() string { return e.stack } func (e *Exception) Code() any { return e.code } func (e *Exception) Message() string { return e.message } func (e *Exception) Data() map[string]any { return e.data } func (e *Exception) ToError() error { if nil == e { return nil } return errors.New(e.Error()) } // IsCode 判断是否为指定错误码 // // Author : go_developer@163.com<白茶清欢> // // Date : 00:39 2023/9/28 func (e *Exception) IsCode(inputCode any) bool { return fmt.Sprintf("%v", inputCode) == fmt.Sprintf("%v", e.Code()) } // NewWithCode 仅使用错误码实例化异常 // // Author : go_developer@163.com<白茶清欢> // // Date : 21:22 2022/6/25 func NewWithCode(code any) IException { return New(code, map[string]any{}, "") } // NewWithCodeAndData 使用 code + data 获取异常实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 21:28 2022/6/25 func NewWithCodeAndData(code any, data map[string]any) IException { return New(code, data, "") } // New 获取异常实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 21:28 2022/6/25 func New(code any, data map[string]any, defaultMessage ...string) IException { if nil == data { // 保证数据结构的一致性, 同时避免后续使用出现空指针 data = map[string]any{} } pcs := make([]uintptr, 128) n := runtime.Callers(2, pcs) frames := runtime.CallersFrames(pcs[:n]) var sb strings.Builder for { frame, more := frames.Next() sb.WriteString(frame.Function) sb.WriteByte('\n') sb.WriteByte('\t') sb.WriteString(frame.File) sb.WriteByte(':') sb.WriteString(strconv.Itoa(frame.Line)) sb.WriteByte('\n') if !more { break } } return &Exception{ code: code, message: GetMessage(code, defaultMessage...), data: data, stack: sb.String(), } } // NewFromError 从error转换为Exception // // Author : go_developer@163.com<白茶清欢> // // Date : 21:36 2022/6/25 func NewFromError(code any, err error) IException { if nil == err { return nil } return New(code, map[string]any{ "err_msg": err.Error(), }, err.Error()) } // NewFromMessage 从 code message 生成exception // // Author : go_developer@163.com<白茶清欢> // // Date : 22:25 2023/2/11 func NewFromMessage(code any, message string) IException { if len(message) == 0 { message = GetMessage(code, "unknown error") } return NewFromError(code, errors.New(message)) } // IsSuccess 判断一个异常是否为成功 // // Author : go_developer@163.com<白茶清欢> // // Date : 21:34 2022/6/25 func IsSuccess(e *Exception) bool { return nil == e || e.IsCode(defaultSuccessCode) } // NewSuccess 代表Success的异常 // // Author : go_developer@163.com<白茶清欢> // // Date : 22:35 2022/6/25 func NewSuccess(data map[string]any) IException { return New(defaultSuccessCode, data, "") }