Skip to content
GitHub no longer supports this web browser. Learn more about the browsers we support.
Golang gRPC helpers, middlewares ...
Go
Branch: master
Clone or download
Cannot retrieve the latest commit at this time.
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
README.md
error.go
panic.interceptor.go

README.md

gRPC helpers, middlewares ... for Golang

Package visigrpc provide some functions to help you making a gRPC server. Errors logged on Sentry, Panic interceptor, HTTP status to gRPC code, ... Everything is made to assist you :)

Table of contents

Install

Use go get to install this package.

go get github.com/visiperf/visigrpc

Usage

Error

The Error(code codes.Code, err error) error function is used to return a gRPC error and log it into Sentry.

type server struct { }

func main() {
  // init Sentry config
  if err := raven.SetDSN(...); err != nil {
    ...
  }
  raven.SetEnvironment(...) 
  
  // gRPC server
  lis, err := net.Listen("tcp", ":9090")
  if err != nil {
    ...
  }
  
  s := grpc.NewServer()
  
  RegisterServiceServer(s, &server{})
  
  if err := s.Serve(lis); err != nil {
    ...
  }
}

func (s *server) Get(ctx context.Context, in *GetRequest) (*GetResponse, error) {
  return nil, visigrpc.Error(codes.Unimplemented, errors.New("implement me"))
}
IMPORTANT : Only Unknown, Internal and DataLoss errors will be reported in Sentry !

From Error

If you receive a gRPC error (made with visigrpc.Error(...) or status.Error(...)), you can decode it with FromError(err error) *grpcError to retrieve the gRPC code and message.

type server struct { }

func main() {
  // init Sentry config
  if err := raven.SetDSN(...); err != nil {
    ...
  }
  raven.SetEnvironment(...) 
  
  // gRPC server
  lis, err := net.Listen("tcp", ":9090")
  if err != nil {
    ...
  }
  
  s := grpc.NewServer()
  
  RegisterServiceServer(s, &server{})
  
  if err := s.Serve(lis); err != nil {
    ...
  }
}

func (s *server) Get(ctx context.Context, in *GetRequest) (*GetResponse, error) {
  return nil, visigrpc.Error(codes.Unimplemented, errors.New("implement me"))
}

func (s *server) Create(ctx context.Context, in *CreateRequest) (*CreateResponse, error) {
  resp, err := s.Get(ctx, &GetRequest{})
  if err != nil {
    ge := visigrpc.FromError(err)
    // ge.Code -> codes.Unimplemented
    // ge.Err -> "implement me"
    ...
  }
  
  return nil, visigrpc.Error(codes.Unimplemented, errors.New("implement me"))
}

gRPC code from HTTP status

If you make an HTTP request, you can use the GrpcCodeFromHttpStatus(status int) codes.Code func to convert HTTP status code in response to gRPC code.

code := GrpcCodeFromHttpStatus(http.StatusForbidden) // http status -> 403 (Forbidden)

// code -> 7 (codes.PermissionDenied)

Panic interceptor

Visigrpc also provide a RecoveryHandler to capture and log panics for Unary and Stream functions.

type server struct { }

func main() {
  // init Sentry config
  if err := raven.SetDSN(...); err != nil {
    ...
  }
  raven.SetEnvironment(...) 
  
  // gRPC server
  lis, err := net.Listen("tcp", ":9090")
  if err != nil {
    ...
  }
  
  var opts = []grpc_recovery.Option{
    grpc_recovery.WithRecoveryHandler(visigrpc.RecoveryHandler),
  }

  s := grpc.NewServer(
    grpc_middleware.WithUnaryServerChain(
       grpc_recovery.UnaryServerInterceptor(opts...),
    ),
    grpc_middleware.WithStreamServerChain(
       grpc_recovery.StreamServerInterceptor(opts...),
    ),
  )
  
  RegisterServiceServer(s, &server{})
  
  if err := s.Serve(lis); err != nil {
    ...
  }
}

func (s *server) Get(ctx context.Context, in *GetRequest) (*GetResponse, error) {
  panic("implement me") // will return codes.Unknown with message "implement me" and log error on Sentry
}

References

You can’t perform that action at this time.