mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-04-06 04:15:46 +08:00
code error
This commit is contained in:
parent
38d3c5d94d
commit
1f935531f6
@ -19,12 +19,8 @@ func apiSuccess(data any) *apiResponse {
|
||||
|
||||
func apiError(err error) *apiResponse {
|
||||
unwrap := errs.Unwrap(err)
|
||||
var dlt string
|
||||
if unwrap != err {
|
||||
dlt = err.Error()
|
||||
}
|
||||
if codeErr, ok := unwrap.(errs.CodeError); ok {
|
||||
return &apiResponse{ErrCode: codeErr.Code(), ErrMsg: codeErr.Msg(), ErrDlt: dlt}
|
||||
return &apiResponse{ErrCode: codeErr.Code(), ErrMsg: codeErr.Msg(), ErrDlt: codeErr.Detail()}
|
||||
}
|
||||
return &apiResponse{ErrCode: errs.ServerInternalError, ErrMsg: err.Error(), ErrDlt: dlt}
|
||||
return &apiResponse{ErrCode: errs.ServerInternalError, ErrMsg: err.Error()}
|
||||
}
|
||||
|
@ -6,10 +6,11 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/errinfo"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GrpcClient() grpc.DialOption {
|
||||
@ -46,8 +47,10 @@ func rpcClientInterceptor(ctx context.Context, method string, req, resp interfac
|
||||
return errs.NewCodeError(errs.ServerInternalError, err.Error()).Wrap()
|
||||
}
|
||||
if details := sta.Details(); len(details) > 0 {
|
||||
if v, ok := details[0].(*wrapperspb.StringValue); ok {
|
||||
return errs.NewCodeError(int(sta.Code()), sta.Message()).Wrap(v.String())
|
||||
errInfo, ok := details[0].(*errinfo.ErrorInfo)
|
||||
if ok {
|
||||
s := strings.Join(errInfo.Warp, "->") + errInfo.Cause
|
||||
return errs.NewCodeError(int(sta.Code()), sta.Message()).WithDetail(s).Wrap()
|
||||
}
|
||||
}
|
||||
return errs.NewCodeError(int(sta.Code()), sta.Message()).Wrap()
|
||||
|
@ -6,13 +6,16 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw/specialerror"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/errinfo"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"math"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const OperationID = "operationID"
|
||||
@ -31,7 +34,22 @@ func rpcServerInterceptor(ctx context.Context, req interface{}, info *grpc.Unary
|
||||
if r := recover(); r != nil {
|
||||
log.ZError(ctx, "rpc panic", nil, "FullMethod", info.FullMethod, "type:", fmt.Sprintf("%T", r), "panic:", r)
|
||||
fmt.Println("stack info:", string(debug.Stack()))
|
||||
err = errs.ErrInternalServer
|
||||
pc, file, line, ok := runtime.Caller(4)
|
||||
if ok {
|
||||
panic("get runtime.Caller failed")
|
||||
}
|
||||
errInfo := &errinfo.ErrorInfo{
|
||||
Path: file,
|
||||
Line: uint32(line),
|
||||
Name: runtime.FuncForPC(pc).Name(),
|
||||
Cause: fmt.Sprintf("%s", r),
|
||||
Warp: nil,
|
||||
}
|
||||
sta, err := status.New(codes.Code(errs.ErrInternalServer.Code()), errs.ErrInternalServer.Msg()).WithDetails(errInfo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = sta.Err()
|
||||
}
|
||||
}()
|
||||
funcName := info.FullMethod
|
||||
@ -68,14 +86,37 @@ func rpcServerInterceptor(ctx context.Context, req interface{}, info *grpc.Unary
|
||||
code = errs.ServerInternalError
|
||||
}
|
||||
grpcStatus := status.New(codes.Code(code), codeErr.Msg())
|
||||
var errInfo *errinfo.ErrorInfo
|
||||
if unwrap != err {
|
||||
stack := fmt.Sprintf("%+v", err)
|
||||
if details, err := grpcStatus.WithDetails(wrapperspb.String(stack)); err == nil {
|
||||
grpcStatus = details
|
||||
sti, ok := err.(interface{ StackTrace() errors.StackTrace })
|
||||
if ok {
|
||||
log.ZWarn(ctx, "rpc server resp", err, "funcName", funcName, "unwrap", unwrap.Error(), "stack", fmt.Sprintf("%+v", err))
|
||||
if fs := sti.StackTrace(); len(fs) > 0 {
|
||||
pc := uintptr(fs[0])
|
||||
fn := runtime.FuncForPC(pc)
|
||||
file, line := fn.FileLine(pc)
|
||||
errInfo = &errinfo.ErrorInfo{
|
||||
Path: file,
|
||||
Line: uint32(line),
|
||||
Name: fn.Name(),
|
||||
Cause: unwrap.Error(),
|
||||
Warp: nil,
|
||||
}
|
||||
if arr := strings.Split(err.Error(), ": "); len(arr) > 1 {
|
||||
errInfo.Warp = arr[:len(arr)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if errInfo == nil {
|
||||
errInfo = &errinfo.ErrorInfo{Cause: err.Error()}
|
||||
}
|
||||
details, err := grpcStatus.WithDetails(errInfo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.ZError(ctx, "rpc server resp", err, "funcName", funcName)
|
||||
return nil, grpcStatus.Err()
|
||||
return nil, details.Err()
|
||||
}
|
||||
|
||||
func GrpcServer() grpc.ServerOption {
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
type CodeError interface {
|
||||
Code() int
|
||||
Msg() string
|
||||
Detail() string
|
||||
WithDetail(detail string) CodeError
|
||||
Is(err error) bool
|
||||
Wrap(msg ...string) error
|
||||
error
|
||||
@ -35,6 +37,24 @@ func (e *codeError) Msg() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
func (e *codeError) Detail() string {
|
||||
return e.detail
|
||||
}
|
||||
|
||||
func (e *codeError) WithDetail(detail string) CodeError {
|
||||
var d string
|
||||
if e.detail == "" {
|
||||
d = detail
|
||||
} else {
|
||||
d = e.detail + ", " + detail
|
||||
}
|
||||
return &codeError{
|
||||
code: e.code,
|
||||
msg: e.msg,
|
||||
detail: d,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *codeError) Wrap(w ...string) error {
|
||||
return errors.Wrap(e, strings.Join(w, ", "))
|
||||
}
|
||||
|
183
pkg/proto/errinfo/errinfo.pb.go
Normal file
183
pkg/proto/errinfo/errinfo.pb.go
Normal file
@ -0,0 +1,183 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc v4.22.0
|
||||
// source: errinfo/errinfo.proto
|
||||
|
||||
package errinfo
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ErrorInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
Line uint32 `protobuf:"varint,2,opt,name=line,proto3" json:"line"`
|
||||
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"`
|
||||
Cause string `protobuf:"bytes,4,opt,name=cause,proto3" json:"cause"`
|
||||
Warp []string `protobuf:"bytes,5,rep,name=warp,proto3" json:"warp"`
|
||||
}
|
||||
|
||||
func (x *ErrorInfo) Reset() {
|
||||
*x = ErrorInfo{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_errinfo_errinfo_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ErrorInfo) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ErrorInfo) ProtoMessage() {}
|
||||
|
||||
func (x *ErrorInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_errinfo_errinfo_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ErrorInfo.ProtoReflect.Descriptor instead.
|
||||
func (*ErrorInfo) Descriptor() ([]byte, []int) {
|
||||
return file_errinfo_errinfo_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ErrorInfo) GetPath() string {
|
||||
if x != nil {
|
||||
return x.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ErrorInfo) GetLine() uint32 {
|
||||
if x != nil {
|
||||
return x.Line
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ErrorInfo) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ErrorInfo) GetCause() string {
|
||||
if x != nil {
|
||||
return x.Cause
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ErrorInfo) GetWarp() []string {
|
||||
if x != nil {
|
||||
return x.Warp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_errinfo_errinfo_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_errinfo_errinfo_proto_rawDesc = []byte{
|
||||
0x0a, 0x15, 0x65, 0x72, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x65, 0x72, 0x72, 0x69, 0x6e, 0x66,
|
||||
0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x4f, 0x70, 0x65, 0x6e, 0x49, 0x4d, 0x53,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0x71,
|
||||
0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x70,
|
||||
0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6c,
|
||||
0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x61, 0x75, 0x73, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x61, 0x75, 0x73, 0x65, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x77, 0x61, 0x72, 0x70, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x77, 0x61, 0x72,
|
||||
0x70, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||
0x4f, 0x70, 0x65, 0x6e, 0x49, 0x4d, 0x53, 0x44, 0x4b, 0x2f, 0x4f, 0x70, 0x65, 0x6e, 0x2d, 0x49,
|
||||
0x4d, 0x2d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2f, 0x65, 0x72, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_errinfo_errinfo_proto_rawDescOnce sync.Once
|
||||
file_errinfo_errinfo_proto_rawDescData = file_errinfo_errinfo_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_errinfo_errinfo_proto_rawDescGZIP() []byte {
|
||||
file_errinfo_errinfo_proto_rawDescOnce.Do(func() {
|
||||
file_errinfo_errinfo_proto_rawDescData = protoimpl.X.CompressGZIP(file_errinfo_errinfo_proto_rawDescData)
|
||||
})
|
||||
return file_errinfo_errinfo_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_errinfo_errinfo_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_errinfo_errinfo_proto_goTypes = []interface{}{
|
||||
(*ErrorInfo)(nil), // 0: OpenIMServer.protobuf.ErrorInfo
|
||||
}
|
||||
var file_errinfo_errinfo_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_errinfo_errinfo_proto_init() }
|
||||
func file_errinfo_errinfo_proto_init() {
|
||||
if File_errinfo_errinfo_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_errinfo_errinfo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ErrorInfo); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_errinfo_errinfo_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_errinfo_errinfo_proto_goTypes,
|
||||
DependencyIndexes: file_errinfo_errinfo_proto_depIdxs,
|
||||
MessageInfos: file_errinfo_errinfo_proto_msgTypes,
|
||||
}.Build()
|
||||
File_errinfo_errinfo_proto = out.File
|
||||
file_errinfo_errinfo_proto_rawDesc = nil
|
||||
file_errinfo_errinfo_proto_goTypes = nil
|
||||
file_errinfo_errinfo_proto_depIdxs = nil
|
||||
}
|
13
pkg/proto/errinfo/errinfo.proto
Normal file
13
pkg/proto/errinfo/errinfo.proto
Normal file
@ -0,0 +1,13 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package OpenIMServer.protobuf;
|
||||
|
||||
option go_package = "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/errinfo";
|
||||
|
||||
message ErrorInfo {
|
||||
string path = 1;
|
||||
uint32 line = 2;
|
||||
string name = 3;
|
||||
string cause = 4;
|
||||
repeated string warp = 5;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
protoc --go_out=plugins=grpc:./auth --go_opt=module=github.com/OpenIMSDK/Open-IM-Server/pkg/proto/auth auth/auth.proto
|
||||
protoc --go_out=plugins=grpc:./conversation --go_opt=module=github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation conversation/conversation.proto
|
||||
protoc --go_out=plugins=grpc:./errinfo --go_opt=module=github.com/OpenIMSDK/Open-IM-Server/pkg/proto/errinfo errinfo/errinfo.proto
|
||||
protoc --go_out=plugins=grpc:./friend --go_opt=module=github.com/OpenIMSDK/Open-IM-Server/pkg/proto/friend friend/friend.proto
|
||||
protoc --go_out=plugins=grpc:./group --go_opt=module=github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group group/group.proto
|
||||
protoc --go_out=plugins=grpc:./msg --go_opt=module=github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg msg/msg.proto
|
||||
|
Loading…
x
Reference in New Issue
Block a user