github.com/lingyao2333/mo-zero@v1.4.1/zrpc/internal/serverinterceptors/crashinterceptor.go (about) 1 package serverinterceptors 2 3 import ( 4 "context" 5 "runtime/debug" 6 7 "github.com/lingyao2333/mo-zero/core/logx" 8 "google.golang.org/grpc" 9 "google.golang.org/grpc/codes" 10 "google.golang.org/grpc/status" 11 ) 12 13 // StreamCrashInterceptor catches panics in processing stream requests and recovers. 14 func StreamCrashInterceptor(svr interface{}, stream grpc.ServerStream, _ *grpc.StreamServerInfo, 15 handler grpc.StreamHandler) (err error) { 16 defer handleCrash(func(r interface{}) { 17 err = toPanicError(r) 18 }) 19 20 return handler(svr, stream) 21 } 22 23 // UnaryCrashInterceptor catches panics in processing unary requests and recovers. 24 func UnaryCrashInterceptor(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, 25 handler grpc.UnaryHandler) (resp interface{}, err error) { 26 defer handleCrash(func(r interface{}) { 27 err = toPanicError(r) 28 }) 29 30 return handler(ctx, req) 31 } 32 33 func handleCrash(handler func(interface{})) { 34 if r := recover(); r != nil { 35 handler(r) 36 } 37 } 38 39 func toPanicError(r interface{}) error { 40 logx.Errorf("%+v\n\n%s", r, debug.Stack()) 41 return status.Errorf(codes.Internal, "panic: %v", r) 42 }