Documentation ¶
Overview ¶
Package grpcutil is a utility package to supplement Google's gRPC package, "google.golang.org/grpc".
Index ¶
- Variables
- func ChainStreamServerInterceptors(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor
- func ChainUnaryServerInterceptors(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
- func Code(err error) codes.Code
- func CodeStatus(code codes.Code) int
- func GRPCifyAndLogErr(ctx context.Context, err error) error
- func IsTransientCode(code codes.Code) bool
- func ModifyServerStreamContext(ss grpc.ServerStream, cb func(context.Context) context.Context) grpc.ServerStream
- func PanicCatcherInterceptor(ctx context.Context, fullMethod string, ...) (err error)
- func WrapIfTransient(err error) error
- func WrapIfTransientOr(err error, extra ...codes.Code) error
- type UnifiedServerInterceptor
Constants ¶
This section is empty.
Variables ¶
var ( CanceledTag = Tag.With(codes.Canceled) UnknownTag = Tag.With(codes.Unknown) InvalidArgumentTag = Tag.With(codes.InvalidArgument) DeadlineExceededTag = Tag.With(codes.DeadlineExceeded) NotFoundTag = Tag.With(codes.NotFound) AlreadyExistsTag = Tag.With(codes.AlreadyExists) PermissionDeniedTag = Tag.With(codes.PermissionDenied) UnauthenticatedTag = Tag.With(codes.Unauthenticated) ResourceExhaustedTag = Tag.With(codes.ResourceExhausted) FailedPreconditionTag = Tag.With(codes.FailedPrecondition) AbortedTag = Tag.With(codes.Aborted) OutOfRangeTag = Tag.With(codes.OutOfRange) UnimplementedTag = Tag.With(codes.Unimplemented) InternalTag = Tag.With(codes.Internal) DataLossTag = Tag.With(codes.DataLoss) )
Shortcuts for assigning tags with codes known at compile time.
Instead errors.Annotate(...).Tag(grpcutil.Tag.With(codes.InvalidArgument)) do errors.Annotate(...).Tag(grpcutil.InvalidArgumentTag)).
var ( // UnaryServerPanicCatcherInterceptor is a grpc.UnaryServerInterceptor that // catches panics in RPC handlers, recovers them and returns codes.Internal gRPC // errors instead. UnaryServerPanicCatcherInterceptor = UnifiedServerInterceptor(PanicCatcherInterceptor).Unary() // StreamServerPanicCatcherInterceptor is a grpc.StreamServerInterceptor that // catches panics in RPC handlers, recovers them and returns codes.Internal gRPC // errors instead. StreamServerPanicCatcherInterceptor = UnifiedServerInterceptor(PanicCatcherInterceptor).Stream() )
var Tag = grpcCodeTag{errors.NewTagKey("gRPC Code")}
Tag may be used to associate a gRPC status code with this error.
The tag value MUST be a "google.golang.org/grpc/codes".Code.
Functions ¶
func ChainStreamServerInterceptors ¶
func ChainStreamServerInterceptors(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor
ChainStreamServerInterceptors chains multiple stream interceptors together.
The first one becomes the outermost, and the last one becomes the innermost, i.e. `ChainStreamServerInterceptors(a, b, c)(h) === a(b(c(h)))`.
nil-valued interceptors are silently skipped.
func ChainUnaryServerInterceptors ¶
func ChainUnaryServerInterceptors(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
ChainUnaryServerInterceptors chains multiple unary interceptors together.
The first one becomes the outermost, and the last one becomes the innermost, i.e. `ChainUnaryServerInterceptors(a, b, c)(h) === a(b(c(h)))`.
nil-valued interceptors are silently skipped.
func Code ¶
Code returns the gRPC code for a given error.
In addition to the functionality of status.Code, this will unwrap any wrapped errors before asking for its code.
If the error is a MultiError containing more than one type of error code, this will return codes.Unknown.
func CodeStatus ¶
CodeStatus maps gRPC codes to HTTP status codes.
Falls back to http.StatusInternalServerError if the code is unrecognized.
func GRPCifyAndLogErr ¶
GRPCifyAndLogErr converts an annotated LUCI error to a gRPC error and logs internal details (including stack trace) for errors with Internal or Unknown codes.
If err is already gRPC error (or nil), it is silently passed through, even if it is Internal. There's nothing interesting to log in this case.
Intended to be used in defer section of gRPC handlers like so:
func (...) Method(...) (resp *pb.Response, err error) { defer func() { err = grpcutil.GRPCifyAndLogErr(c, err) }() ... }
func IsTransientCode ¶
IsTransientCode returns true if a given gRPC code is codes.Internal, codes.Unknown or codes.Unavailable.
func ModifyServerStreamContext ¶
func ModifyServerStreamContext(ss grpc.ServerStream, cb func(context.Context) context.Context) grpc.ServerStream
ModifyServerStreamContext returns a ServerStream that fully wraps the given one except its context is modified based on the result of the given callback.
This is handy when implementing stream server interceptors that need to put stuff into the stream's context.
The callback will be called immediately and only once. It must return a context derived from the context it receives or nil if the context modification is not actually necessary.
func PanicCatcherInterceptor ¶
func PanicCatcherInterceptor(ctx context.Context, fullMethod string, handler func(ctx context.Context) error) (err error)
PanicCatcherInterceptor is a UnifiedServerInterceptor that catches panics in RPC handlers, recovers them and returns codes.Internal gRPC errors instead.
func WrapIfTransient ¶
WrapIfTransient wraps the supplied gRPC error with a transient wrapper if its gRPC code is transient as determined by IsTransientCode.
If the supplied error is nil, nil will be returned.
Note that non-gRPC errors will have code codes.Unknown, which is considered transient, and be wrapped. This function should only be used on gRPC errors.
Also note that codes.DeadlineExceeded is not considered a transient error, since it is often non-retriable (e.g. if the root context has expired, no amount of retries will resolve codes.DeadlineExceeded error).
Types ¶
type UnifiedServerInterceptor ¶
type UnifiedServerInterceptor func(ctx context.Context, fullMethod string, handler func(ctx context.Context) error) error
UnifiedServerInterceptor can be converted into an unary or stream server interceptor.
Such interceptor can do something at the start of the request (in particular modify the request context) and do something with the request error at the end. It can also skip the request entirely by returning an error without calling the handler.
It is handy when implementing simple interceptors that can be used as both unary and stream ones.
func (UnifiedServerInterceptor) Stream ¶
func (u UnifiedServerInterceptor) Stream() grpc.StreamServerInterceptor
Stream returns a stream form of the interceptor.
func (UnifiedServerInterceptor) Unary ¶
func (u UnifiedServerInterceptor) Unary() grpc.UnaryServerInterceptor
Unary returns an unary form of the interceptor.