status

package
v2.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2024 License: MIT Imports: 10 Imported by: 1

Documentation

Overview

Package status is a drop-in replacement for the google.golang.org/grpc/status package, but is compatible with merry errors.

Errors created by this package are merry errors, and can be augmented with additional information, like any other merry error.

Functions which translate errors into a Status, or into a Code are compatible with the new error wrapping conventions, using errors.Is and errors.As to extract a Status from nested errors.

This package also adds additional utilities for adding Codes to an existing error, and converting a merry error into a Status.

Index

Constants

This section is empty.

Variables

View Source
var DefaultLocalizedMessageLocale = "en-US"

DefaultLocalizedMessageLocale is the value used when encoding a merry.UserMessage() to a errdetails.LocalizedMessage.

Functions

func AttachStatus added in v2.1.0

func AttachStatus(err error, status *Status) error

AttachStatus associates a Status with an error. status.FromError and status.Convert will return this value instead of deriving a status from the error.

This should be used by GRPC handlers which want to craft a specific status.Status to return. The result of this function should be returned by the handler *without any further error wrapping* (because grpc does not support error wrapping), like this:

func MyHandler(ctx context.Context, req *MyReq) (*MyResp, error) {
  resp, err := handle(ctx, req)
  if err != nil {
    sts := status.Convert(err)
    // customize the status
    return nil, status.AttachStatus(err, sts)
  }
}

tl;dr

This would typically be done like this:

func MyHandler(ctx context.Context, req *MyReq) (*MyResp, error) {
  resp, err := handle(ctx, req)
  if err != nil {
    sts := status.Convert(err)
    // customize the status
    return nil, status.Err()
  }
}

The trouble with that is that the original error is lost. If you have interceptors which log errors, they will never see the original error, which might have had all sorts of interesting information in them. You also can't do this:

return merry.Wrap(sts.Err(), merry.WithCause(err))

...because the grpc package doesn't handle wrapped errors. You cannot wrap sts.Err() any further, or the status will be lost. According to this PR, it seems this is intentional, and wrapped errors may never be supported.

This is intentionally *not* a merry wrapper function, because the result of this function should never be wrapped any further. It needs to be returned as-is from the handler in order for the grpc code to find your status.Status and return it to the client.

func Code

func Code(err error) codes.Code

Code returns the grpc response code for an error. It is similar to status.Code(), and should behave identically to that function for non-merry errors. If err is a merry error, this supports mapping some merry constructs to grpc codes. The rules like a switch statement:

- err is nil: codes.OK - code previously set with WithCode() - errors.As(GRPCStatuser): return code from Status - errors.Is(context.DeadlineExceeded): codes.DeadlineExceeded - errors.Is(context.Canceled: codes.Canceled - default: CodeFromHTTPStatus(), which defaults to codes.Unknown

func CodeFromHTTPStatus

func CodeFromHTTPStatus(httpStatus int) codes.Code

CodeFromHTTPStatus returns a grpc code from an http status code. It returns the inverse of github.com/grpc-ecosystem/grpc-gateway/v2/runtime.HTTPStatusFromCode, plus some additional HTTP code mappings.

If there is no mapping for the status code, it defaults to OK for status codes between 200 and 299, and Unknown for all others.

func DetailsFromError

func DetailsFromError(err error) []proto.Message

DetailsFromError derives status details from context attached to the error:

- if the err has a user message, it will be converted into a LocalizedMessage. - if the err has a stack, it will be converted into a DebugInfo.

Returns nil if no details are derived from the error.

func Error

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

Error returns an error representing c and msg. If c is OK, returns nil.

func ErrorProto

func ErrorProto(s *spb.Status) error

ErrorProto returns an error representing s. If s.Code is OK, returns nil.

func Errorf

func Errorf(c codes.Code, format string, a ...interface{}) error

Errorf returns Error(c, fmt.Sprintf(format, a...)).

func WithCode

func WithCode(code codes.Code) merry.Wrapper

WithCode is a merry.Wrapper which associates a GRPC code with the error. Code() will return this value.

Types

type GRPCStatuser

type GRPCStatuser interface {
	GRPCStatus() *Status
}

GRPCStatuser knows how to return a Status.

type Status

type Status = status.Status

Status references google.golang.org/grpc/status

func Convert

func Convert(err error) *Status

Convert is a convenience function which removes the need to handle the boolean return value from FromError.

func FromContextError

func FromContextError(err error) *Status

FromContextError remains for compatibility with the status package, but it does the same thing as Convert/FromError. The logic for translating context errors into appropriate grpc codes is built in to FromError now.

func FromError

func FromError(err error) (s *Status, ok bool)

FromError returns a Status representing err if the error or any of its causes can be coerced to a GRPCStatuser with errors.As(). Errors created by this package or by google.golang.org/grpc/status have a Status that will be found by this function. A Status can also be associated with an existing error using WithStatus.

If a Status is found, the ok return value will be true.

If no Status is found, ok is false, and a new Status is constructed from the error.

func FromProto

func FromProto(s *spb.Status) *Status

FromProto returns a Status representing s.

func New

func New(c codes.Code, msg string) *Status

New returns a Status representing c and msg.

func Newf

func Newf(c codes.Code, format string, a ...interface{}) *Status

Newf returns New(c, fmt.Sprintf(format, a...)).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL