Package grpcutil is a utility package to supplement Google's gRPC package, "".



This section is empty.


View Source
var (
	// Errf falls through to status.Errorf, with the notable exception that it isn't
	// named "Errorf" and, consequently, won't trigger "go vet" misuse errors.
	Errf = status.Errorf

	// OK is an empty grpc.OK status error.
	OK = Errf(codes.OK, "")

	// Canceled is an empty grpc.Canceled error.
	Canceled = Errf(codes.Canceled, "")

	// Unknown is an empty grpc.Unknown error.
	Unknown = Errf(codes.Unknown, "")

	// InvalidArgument is an empty grpc.InvalidArgument error.
	InvalidArgument = Errf(codes.InvalidArgument, "")

	// DeadlineExceeded is an empty grpc.DeadlineExceeded error.
	DeadlineExceeded = Errf(codes.DeadlineExceeded, "")

	// NotFound is an empty grpc.NotFound error.
	NotFound = Errf(codes.NotFound, "")

	// AlreadyExists is an empty grpc.AlreadyExists error.
	AlreadyExists = Errf(codes.AlreadyExists, "")

	// PermissionDenied is an empty grpc.PermissionDenied error.
	PermissionDenied = Errf(codes.PermissionDenied, "")

	// Unauthenticated is an empty grpc.Unauthenticated error.
	Unauthenticated = Errf(codes.Unauthenticated, "")

	// ResourceExhausted is an empty grpc.ResourceExhausted error.
	ResourceExhausted = Errf(codes.ResourceExhausted, "")

	// FailedPrecondition is an empty grpc.FailedPrecondition error.
	FailedPrecondition = Errf(codes.FailedPrecondition, "")

	// Aborted is an empty grpc.Aborted error.
	Aborted = Errf(codes.Aborted, "")

	// OutOfRange is an empty grpc.OutOfRange error.
	OutOfRange = Errf(codes.OutOfRange, "")

	// Unimplemented is an empty grpc.Unimplemented error.
	Unimplemented = Errf(codes.Unimplemented, "")

	// Internal is an empty grpc.Internal error.
	Internal = Errf(codes.Internal, "")

	// Unavailable is an empty grpc.Unavailable error.
	Unavailable = Errf(codes.Unavailable, "")

	// DataLoss is an empty grpc.DataLoss error.
	DataLoss = Errf(codes.DataLoss, "")
View Source
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)
	UnavailableTag        = Tag.With(codes.Unavailable)
	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)).

View Source
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 "".Code.


func ChainUnaryServerInterceptors

func ChainUnaryServerInterceptors(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor

ChainUnaryServerInterceptors chains multiple 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

func Code(err error) codes.Code

Code returns the gRPC code for a given error.

In addition to the functionality of grpc.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

func CodeStatus(code codes.Code) int

CodeStatus maps gRPC codes to HTTP status codes. Falls back to http.StatusInternalServerError.

func GRPCifyAndLogErr

func GRPCifyAndLogErr(c context.Context, err error) error

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

func IsTransientCode(code codes.Code) bool

IsTransientCode returns true if a given gRPC code is associated with a transient gRPC error type.

func ToGRPCErr

func ToGRPCErr(err error) error

ToGRPCErr is a shorthand for Errf(Code(err), "%s", err)

func UnaryServerPanicCatcherInterceptor

func UnaryServerPanicCatcherInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error)

UnaryServerPanicCatcherInterceptor is a grpc.UnaryServerInterceptor that catches panics in RPC handlers, recovers them and returns codes.Internal gRPC errors instead.

func WrapIfTransient

func WrapIfTransient(err error) error

WrapIfTransient wraps the supplied gRPC error with a transient wrapper if it has a transient gRPC code, as determined by IsTransientCode.

If the supplied error is nil, nil will be returned.

Note that non-gRPC errors will have code grpc.Unknown, which is considered transient, and be wrapped. This function should only be used on gRPC errors.


This section is empty.