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  }