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  }