github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/go-grpc-middleware/recovery/interceptors.go (about) 1 // Copyright 2017 David Ackroyd. All Rights Reserved. 2 // See LICENSE for licensing terms. 3 4 package grpc_recovery 5 6 import ( 7 "github.com/hxx258456/ccgo/grpc" 8 "github.com/hxx258456/ccgo/grpc/codes" 9 "github.com/hxx258456/ccgo/net/context" 10 ) 11 12 // RecoveryHandlerFunc is a function that recovers from the panic `p` by returning an `error`. 13 type RecoveryHandlerFunc func(p interface{}) (err error) 14 15 // RecoveryHandlerFuncContext is a function that recovers from the panic `p` by returning an `error`. 16 // The context can be used to extract request scoped metadata and context values. 17 type RecoveryHandlerFuncContext func(ctx context.Context, p interface{}) (err error) 18 19 // UnaryServerInterceptor returns a new unary server interceptor for panic recovery. 20 func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor { 21 o := evaluateOptions(opts) 22 return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { 23 defer func() { 24 if r := recover(); r != nil { 25 err = recoverFrom(ctx, r, o.recoveryHandlerFunc) 26 } 27 }() 28 29 return handler(ctx, req) 30 } 31 } 32 33 // StreamServerInterceptor returns a new streaming server interceptor for panic recovery. 34 func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor { 35 o := evaluateOptions(opts) 36 return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { 37 defer func() { 38 if r := recover(); r != nil { 39 err = recoverFrom(stream.Context(), r, o.recoveryHandlerFunc) 40 } 41 }() 42 43 return handler(srv, stream) 44 } 45 } 46 47 func recoverFrom(ctx context.Context, p interface{}, r RecoveryHandlerFuncContext) error { 48 if r == nil { 49 return grpc.Errorf(codes.Internal, "%s", p) 50 } 51 return r(ctx, p) 52 }