Documentation ¶
Overview ¶
Easy-to-use rich errors between services and clients.
Index ¶
- Constants
- Variables
- func CatchPanic(run func() error) (err error)
- func NewErrNotFoundMiddleware(errGen *ErrorGenerator) pkmiddleware.UnaryServerMiddleware
- func ReissueDefaultSentinels(issuer string, offset int)
- type APIError
- type Error
- type ErrorGenerator
- func (gen *ErrorGenerator) NewErr(sentinel *SentinelError, message string, details []proto.Message, source error) (apiErr error)
- func (gen *ErrorGenerator) StreamClientMiddleware(next pkmiddleware.StreamClientHandler) pkmiddleware.StreamClientHandler
- func (gen *ErrorGenerator) StreamServerMiddleware(next pkmiddleware.StreamServerHandler) pkmiddleware.StreamServerHandler
- func (gen *ErrorGenerator) UnaryClientMiddleware(next pkmiddleware.UnaryClientHandler) pkmiddleware.UnaryClientHandler
- func (gen *ErrorGenerator) UnaryServerMiddleware(next pkmiddleware.UnaryServerHandler) pkmiddleware.UnaryServerHandler
- func (gen ErrorGenerator) WithAppName(appName string) *ErrorGenerator
- type GrpcCodeErr
- type PanicError
- type SentinelError
- type SentinelIssuer
- type TraceInfo
Examples ¶
Constants ¶
const DefaultsIssuer = "GRPEAKEC"
Variables ¶
var ErrAlreadyExists = sentinelIssuer.NewSentinel( "AlreadyExists", 1002, codes.AlreadyExists, "resource already exists", )
ErrAlreadyExists is the default error for requesting a resource that already exists.
var ErrNotFound = sentinelIssuer.NewSentinel( "ResourceExists", 1001, codes.NotFound, "requested resource not found", )
ErrNotFound is the default error for requesting a resource that does not exist.
var ErrUnknown = sentinelIssuer.NewSentinel( "Unknown", 1000, codes.Unknown, "an unknown error occurred", )
ErrUnknown is the default fallback error that is returned from a server interceptor when an incoming error is not an APIError, *Error, or SentinelError value.
var ErrValidation = sentinelIssuer.NewSentinel( "Validation", 1003, codes.InvalidArgument, "client argument failed validation", )
ErrValidation should be returned when a request fails validation.
Functions ¶
func CatchPanic ¶
CatchPanic takes in a function with an error return, catches any panics that occur, and converts them to PanicError. Returned errors are passed up as-is.
func NewErrNotFoundMiddleware ¶ added in v0.0.5
func NewErrNotFoundMiddleware( errGen *ErrorGenerator, ) pkmiddleware.UnaryServerMiddleware
NewErrNotFoundMiddleware returns ErrNotFound on any unary calls that return both a nil response and a nil error.
By using a generator we assure that any included stacktrace points back to this middleware definitively.
func ReissueDefaultSentinels ¶
ReissueDefaultSentinels applies the issuer and offset to all the default SentinelError values found in this package, such as ErrUnknown.
Types ¶
type APIError ¶
type APIError struct { Proto *Error Sentinel *SentinelError Source error }
APIError holds the protobuf *Error and adds some runtime context to it. In general, callers should not be working directly with the *Error type, and should be using APIError instead.
type ErrorGenerator ¶
type ErrorGenerator struct {
// contains filtered or unexported fields
}
ErrorGenerator generates errors with app-specific settings.
func NewErrGenerator ¶
func NewErrGenerator( appName string, addHost bool, addStackTrace bool, sendContext bool, sendSource bool, ) *ErrorGenerator
Creates a new Error generator.
appName and hostName are both applied to *TraceInfo frames added through this generator's grpc client interceptors as well as the initial frame from ErrorGenerator.NewErr.
addStackTrace will cause a full debug stacktrace to be added when a *TraceInfo value is created by this generator.
Example ¶
package main import ( "github.com/peake100/gRPEAKEC-go/pkerr" ) func main() { // This error generator can be used to create sentinels and errors on the client // side. _ = pkerr.NewErrGenerator( "PingServer", // appName true, // addHost true, // addStackTrace true, // sendContext true, // sendSource ) }
Output:
func (*ErrorGenerator) NewErr ¶
func (gen *ErrorGenerator) NewErr( sentinel *SentinelError, message string, details []proto.Message, source error, ) (apiErr error)
NewErr creates a new error with the code, name, issuer, and grpc status code of sentinel.
func (*ErrorGenerator) StreamClientMiddleware ¶ added in v0.0.4
func (gen *ErrorGenerator) StreamClientMiddleware( next pkmiddleware.StreamClientHandler, ) pkmiddleware.StreamClientHandler
StreamClientMiddleware implements pkmiddleware.StreamClientMiddleware and converts incoming errors to an APIError if the error contains an *Error detail, and a new *TraceInfo frame will be added.
*Error values are generated using the settings of ErrorGenerator.
func (*ErrorGenerator) StreamServerMiddleware ¶ added in v0.0.4
func (gen *ErrorGenerator) StreamServerMiddleware( next pkmiddleware.StreamServerHandler, ) pkmiddleware.StreamServerHandler
StreamServerMiddleware implements pkmiddleware.StreamServerMiddleware that can handle wrapping all errors and panics in an APIError and transforming them into a status.Status.
func (*ErrorGenerator) UnaryClientMiddleware ¶ added in v0.0.4
func (gen *ErrorGenerator) UnaryClientMiddleware( next pkmiddleware.UnaryClientHandler, ) pkmiddleware.UnaryClientHandler
UnaryClientMiddleware implements pkmiddleware.UnaryClientMiddleware and handles decoding an *Error detail as an APIError.
If an *Error detail message is found in the status of an error return, the message will be extracted into an APIError, and a new *TraceInfo frame will be added.
*Error values are generated using the settings of ErrorGenerator.
func (*ErrorGenerator) UnaryServerMiddleware ¶ added in v0.0.4
func (gen *ErrorGenerator) UnaryServerMiddleware( next pkmiddleware.UnaryServerHandler, ) pkmiddleware.UnaryServerHandler
NewUnaryServerInterceptor implements pkmiddleware.UnaryServerMiddleware that can handle wrapping all errors and panics in an APIError and transforming them into a status.Status.
func (ErrorGenerator) WithAppName ¶
func (gen ErrorGenerator) WithAppName(appName string) *ErrorGenerator
WithAppName returns a copy of the ErrorGenerator with the appName setting replaced.
type GrpcCodeErr ¶
GrpcCodeErr can be used to wrap codes.Code when checking if an APIError is from a specific codes.Code using errors.Is.
type PanicError ¶
type PanicError struct { // Source is the recovered error. If the value from recover() is not an error type // it will be coerce into an error string with format: "%+v" Recovered interface{} }
PanicError wraps a recover() panic value as an error.
func (PanicError) Unwrap ¶
func (err PanicError) Unwrap() error
Unwrap implements xerrors.Wrapper. If the underlying Recovered value is an error, it will be returned, otherwise an error-string will be returned.
type SentinelError ¶
type SentinelError struct { // Issuer is the issuer of a code. If multiple services use this library, they // can differentiate their error codes by having unique issuers. If a number of // services working together in the same backend coordinate to ensure their error // definitions do not overlap, they can share an Issuer value. Issuer string // The error code that defines this error. Code uint32 // Human-readable name tied to the error Code. Name string // GrpcCode is the status.Status.Code that grpc servers should set when reporting // this error. GrpcCode codes.Code // The default message to be returned by the sentinel version of this def. DefaultMessage string // contains filtered or unexported fields }
SentinelError is used for creating sentinel errors within the go implementation of a backend for given Error codes for quick errors.Is() checking.
Issuer "", API coded 1000-1999 are reserved by grpcErr for creating a set of default error codes.
The base code for unknown error is 1000.
func (*SentinelError) As ¶
func (code *SentinelError) As(target interface{}) bool
As allows extracting a wrapped SentinelError as an APIError.
func (*SentinelError) Error ¶
func (code *SentinelError) Error() string
Error implements builtins.error
type SentinelIssuer ¶ added in v0.0.2
type SentinelIssuer struct {
// contains filtered or unexported fields
}
SentinelIssuer issues new sentinel errors
func NewSentinelIssuer ¶ added in v0.0.2
func NewSentinelIssuer(issuer string, applyEnvSettings bool) *SentinelIssuer
NewSentinelIssuer returns a new *SentinelIssuer.
issuer is the value to use for all *SentinelError values created with ErrorGenerator.NewSentinel.
applyEnvSettings loads issuer and code offset information from environmental variables and applies them to the generator, using the current settings as default if no env var is found.
The environmental variables are the following:
- [AppName]_ERROR_ISSUER - [AppName]_ERROR_CODE_OFFSET
By having these settings configurable as environmental variables, two generic services that both use this error library can be merged into a single backend, and appear more uniform to a caller by having the same issuer.
The code offset ensures that error codes can be shifted so they do not collide when two generic services are used in the same backend.
func (*SentinelIssuer) ApplyNewIssuer ¶ added in v0.0.2
func (sentinels *SentinelIssuer) ApplyNewIssuer(issuer string, offset int)
ApplyNewIssuer rewrites all issued sentinels to have the given issuer and offset.
func (*SentinelIssuer) NewSentinel ¶ added in v0.0.2
func (sentinels *SentinelIssuer) NewSentinel( name string, code uint32, grpcCode codes.Code, defaultMessage string, ) *SentinelError
NewSentinel creates a new *SentinelError and saves the pointer so it can be altered / offset later.