Back to godoc.org
go.chromium.org/luci / grpc / appstatus

Package appstatus

v0.0.0-...-5f48781
Latest Go to latest

The latest major version is .

Published: 1 hour ago | License: Apache-2.0 | Module: go.chromium.org/luci

Overview

Package appstatus can attach/reterieve an application-specific response status to/from an error. It designed to prevent accidental exposure of internal statuses to RPC clients, for example Spanner's statuses.

Attaching a status

Use ToError, Error and Errorf to create new status-annotated errors. Use Attach and Attachf to annotate existing errors with a status.

if req.PageSize < 0  {
   return appstatus.Errorf(codes.InvalidArgument, "page size cannot be negative")
}
if err := checkState(); err != nil {
  return appstatus.Attachf(err, codes.PreconditionFailed, "invalid state")
}

This may be done deep in the function call hierarchy.

Do not use appstatus in code where you don't explicitly intend to return a specific status. This is unnecessary because any unrecognized error is treated as internal and because it is explicitly prohibited to attach a status to an error chain multiple times. When a status is attached, the package supports its propagation all the way to the requester unless there is code that explicitly throws it away.

Returning a status

Use GRPCifyAndLog right before returning the error from a gRPC method handler. Usually it is done in a Postlude of a service decorator, see ../cmd/svcdec.

func NewMyServer() pb.MyServer {
  return &pb.DecoratedMyServer{
    Service:  &actualImpl{},
    Postlude: func(ctx context.Context, methodName string, rsp proto.Message, err error) error {
      return appstatus.GRPCifyAndLog(ctx, err)
    },
  }
}

It recognizes only appstatus-annotated errors and treats any other error as internal. This behavior is important to avoid accidentally returning errors from Spanner or other client library that also uses grpc/status package to communicate status code from *other* services. For example, if a there is a typo in Spanner SQL statement, spanner package may return a status-annotated errors with code NotFound. In this case, our RPC must respond with internal error and not NotFound.

Index

func Attach

func Attach(err error, status *status.Status) error

Attach attaches an application-specific status to the error. The status will be shared with the RPC client as is. If err already has an application-specific status attached, panics.

func Attachf

func Attachf(err error, code codes.Code, format string, args ...interface{}) error

Attachf is a shortcut for Attach(err, status.Newf(...))

func BadRequest

func BadRequest(err error, details ...*errdetails.BadRequest) error

BadRequest annotates err as a bad request. The error message is shared with the requester as is.

func Error

func Error(code codes.Code, msg string) error

Error returns an error with an application-specific status. The message will be shared with the RPC client as is.

func Errorf

func Errorf(code codes.Code, format string, args ...interface{}) error

Errorf returns an error with an application-specific status. The message will be shared with the RPC client as is.

func GRPCifyAndLog

func GRPCifyAndLog(ctx context.Context, err error) error

GRPCifyAndLog returns a GRPC error. If the error doesn't have a GRPC status attached by this package, internal error is assumed. Any internal or unknown errors are logged.

func Get

func Get(err error) (st *status.Status, ok bool)

Get returns an application-specific Status attached to err using this package. If not explicitly set or if err is nil, then ok is false.

func MustWithDetails

func MustWithDetails(s *status.Status, details ...proto.Message) *status.Status

MustWithDetails adds details to a status and asserts it is successful.

func ToError

func ToError(s *status.Status) error

ToError converts an application-specific status to an error.

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier