package myerrors import ( "context" "fmt" "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/glog" "github.com/gogf/gf/v2/util/gconv" "github.com/smallnest/rpcx/codec" "github.com/smallnest/rpcx/protocol" "github.com/smallnest/rpcx/share" "strings" ) var ( codeTipsErr = gcode.New(1001, "错误提示", nil) codeValidErr = gcode.New(1002, "数据校验失败", nil) codeQueryErr = gcode.New(1003, "%s查询失败", nil) codeCreateErr = gcode.New(1004, "%s创建失败", nil) codeUpdateErr = gcode.New(1005, "%s更新失败", nil) codeDeleteErr = gcode.New(1006, "%s删除失败", nil) codeAuthErr = gcode.New(1010, "登录失效或认证失败,请重新尝试", nil) codePermErr = gcode.New(1011, "权限验证失败,请重新尝试", nil) codeMicroCallErr = gcode.New(1100, "微服务调用失败,请重新尝试", nil) codeConvErr = gcode.New(1200, "数据转换异常,请重新尝试", nil) codeDbErr = gcode.New(1201, "数据库操作异常,请重新尝试", nil) codeThirdPluginErr = gcode.New(1301, "第三方组件异常:%s", nil) codeSysErr = gcode.New(500, "系统异常,请重新尝试", nil) ) func New(errCode int, err error, errMsg ...string) error { if err == nil { return gerror.NewCode(gcode.New(errCode, "自定义异常", nil), errMsg...) } return gerror.WrapCode(gcode.New(errCode, "自定义异常", nil), err, errMsg...) } func TipsError(errMsg string) error { return gerror.NewCode(codeTipsErr, errMsg) } func ValidError(errMsg ...string) error { return gerror.NewCode(codeValidErr, handleErrMsg(codeValidErr, errMsg...)) } func QueryError(err error, module string) error { return gerror.WrapCodef(codeQueryErr, err, codeQueryErr.Message(), module) } func CreateError(err error, module string) error { return gerror.WrapCodef(codeCreateErr, err, codeCreateErr.Message(), module) } func UpdateError(err error, module string) error { return gerror.WrapCodef(codeUpdateErr, err, codeUpdateErr.Message(), module) } func DeleteError(err error, module string) error { return gerror.WrapCodef(codeDeleteErr, err, codeDeleteErr.Message(), module) } func AuthError(errMsg ...string) error { return gerror.NewCode(codeAuthErr, handleErrMsg(codeAuthErr, errMsg...)) } func PermError(errMsg ...string) error { return gerror.NewCode(codePermErr, handleErrMsg(codePermErr, errMsg...)) } func MicroCallError(errMsg ...string) error { return gerror.NewCode(codeMicroCallErr, handleErrMsg(codeMicroCallErr, errMsg...)) } func ConvError(errMsg ...string) error { return gerror.NewCode(codeConvErr, handleErrMsg(codeConvErr, errMsg...)) } func DbError(errMsg ...string) error { return gerror.NewCode(codeDbErr, handleErrMsg(codeDbErr, errMsg...)) } func ThirdPluginError(err error, module string) error { return gerror.WrapCodef(codeThirdPluginErr, err, codeThirdPluginErr.Message(), module) } func SysError() error { return gerror.NewCode(codeSysErr, codeSysErr.Message()) } func handleErrMsg(errCode gcode.Code, errMsg ...string) string { msg := errCode.Message() if len(errMsg) > 0 { msg = errCode.Message() + ": " + strings.Join(errMsg, ", ") } return msg } type HandleErrorPlugin struct{} func (p HandleErrorPlugin) getSerializeType(mes *protocol.Message) (codec.Codec, g.Map) { var err error serializer := share.Codecs[mes.SerializeType()] data := g.Map{} switch mes.SerializeType() { case protocol.SerializeNone: case protocol.JSON: err = serializer.Decode(mes.Payload, &data) case protocol.ProtoBuffer: case protocol.MsgPack: err = serializer.Decode(mes.Payload, &data) case protocol.Thrift: } fmt.Println(err) return serializer, data } func (p HandleErrorPlugin) PreWriteResponse(ctx context.Context, req *protocol.Message, res *protocol.Message, err error) error { serializer := share.Codecs[res.SerializeType()] resData := make(g.Map) if res.Payload != nil { if serializerErr := serializer.Decode(res.Payload, &resData); serializerErr != nil { return serializerErr } } if err == nil { // todo 正常数据处理 if gconv.Int(resData["code"]) == 0 || gconv.Int(resData["Code"]) == 0 { resData["code"] = 200 } if resData["msg"] == "" || resData["Msg"] == "" { resData["msg"] = "操作成功" } resData["Code"] = resData["code"] resData["Msg"] = resData["msg"] res.Payload, _ = serializer.Encode(resData) return nil } // error 堆栈信息输出 glog.Error(ctx, gerror.Stack(err)) topCode := gerror.Code(err).Code() // 检查是否存在二级错误,如存在取底层错误信息 gNextError := gerror.Unwrap(err) nextErrCode := topCode if gNextError != nil { nextErrCode = gerror.Code(gNextError).Code() } switch true { case nextErrCode > 1000: // 业务级异常处理 resData["code"] = int32(topCode) resData["msg"] = err.Error() case nextErrCode == gcode.CodeValidationFailed.Code(): // goframe 数据校验 // 检查是否存在业务信息,添加显示 resData["code"] = int32(codeValidErr.Code()) resData["msg"] = codeValidErr.Message() + ": " + err.Error() case nextErrCode > 0 && topCode > 1000: // 检查是否存在业务信息,添加显示 resData["code"] = int32(topCode) resData["msg"] = splitErrorStr(err.Error()) default: // 默认返回系统级异常处理 resData["code"] = int32(codeSysErr.Code()) resData["msg"] = codeSysErr.Message() } resData["Code"] = resData["code"] resData["Msg"] = resData["msg"] res.Payload, _ = serializer.Encode(resData) res.SetMessageStatusType(protocol.Normal) if res.Metadata != nil { delete(res.Metadata, protocol.ServiceError) } return nil } func splitErrorStr(errMsg string) string { errStrIndex := strings.Index(errMsg, ": ") return errMsg[:errStrIndex] + ": " + codeSysErr.Message() }