Documentation ¶
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(err error, status *status.Status) error
- func Attachf(err error, code codes.Code, format string, args ...interface{}) error
- func BadRequest(err error, details ...*errdetails.BadRequest) error
- func Error(code codes.Code, msg string) error
- func Errorf(code codes.Code, format string, args ...interface{}) error
- func GRPCifyAndLog(ctx context.Context, err error) error
- func Get(err error) (st *status.Status, ok bool)
- func MustWithDetails(s *status.Status, details ...proto.Message) *status.Status
- func ToError(s *status.Status) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Attach ¶
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 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 ¶
Error returns an error with an application-specific status. The message will be shared with the RPC client as is.
func Errorf ¶
Errorf returns an error with an application-specific status. The message will be shared with the RPC client as is.
func GRPCifyAndLog ¶
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 ¶
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 ¶
MustWithDetails adds details to a status and asserts it is successful.
Types ¶
This section is empty.