errors

package
v0.0.0-...-b349366 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2020 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package errors implements a common interface for errors to be communicated within and between components of a multi-service architecture.

It relies on the concept of describing your errors statically and then building actual instances of the errors when they occur.

The resulting errors are uniquely identifiable so their orginal descriptions can be retreived. This makes it easier to localize the error messages since we can enumerate all possible errors.

There's only one restriction: all services that use error descriptors must ensure that their Codes are unique. This is really a cross-service restriction that cannot be enforced by the package itself so some hygiene and discpline is required here. To aid with this, use the Range function to create a code range that is disjunct from other ranges.

Example
// define the range your error codes should be in
code := Range(10000, 120000)

// ErrSomeUserMistake is the description of the error some user made
// that costs the company some money
ErrSomeUserMistake := &ErrDescriptor{
	// MessageFormat is the format the error message will be using
	// It is written in ICU message format
	MessageFormat: "You made a mistake cost us {price, plural, =0 {no money} =1 {one dollar} other {{price} dollars}}",

	// Type is the general category of the error (like HTTP status codes it puts
	// the error in a category that clients can understand without knowing the
	// error).
	Type: InvalidArgument,

	// Code is the unique code of this error
	Code: code(391),
}

// register the error so others can find it based on Code
ErrSomeUserMistake.Register()

// Create a new error based on the descriptor
err := ErrSomeUserMistake.New(Attributes{
	"price": 7,
})

// this will print the formatted error message
fmt.Println(err)
Output:

Index

Examples

Constants

View Source
const CodeHeader = "X-TTN-Error-Code"

CodeHeader is the header where the error code will be stored

Variables

This section is empty.

Functions

func Cause

func Cause(err Error) error

Cause returns the cause of an error

func Format

func Format(format string, values Attributes) string

Format formats the values into the provided string

func GRPCCode

func GRPCCode(err error) codes.Code

GRPCCode returns the corresponding http status code from an error

func GetMessageFormat

func GetMessageFormat(err error) string

GetMessageFormat infers the message format from the error or falls back to the error message

func HTTPStatusCode

func HTTPStatusCode(err error) int

HTTPStatusCode returns the HTTP status code for the given error or 500 if it doesn't know

func Range

func Range(start uint32, end uint32) func(uint32) Code

Range is a utility function that creates a code builder.

Example:

	var code = Range(1000, 2000)
 var ErrSomethingWasWrong := &ErrDescriptor{
		// ...
		Code: code(77),
 }

This can be used to create disjunct code ranges and be strict about it. The codes created by the returned function will range from start (inclusive) to end (exclusive) or the function will panic otherwise.

func Register

func Register(descriptors ...*ErrDescriptor)

Register registers a new error descriptor

func ToGRPC

func ToGRPC(in error) error

ToGRPC turns an error into a gRPC error

func ToHTTP

func ToHTTP(in error, w http.ResponseWriter) error

ToHTTP writes the error to the http response

Types

type Attributes

type Attributes map[string]interface{}

Attributes is a map of attributes

func GetAttributes

func GetAttributes(err error) Attributes

GetAttributes returns the error attributes or falls back to empty attributes

type Causer

type Causer interface {
	Cause() error
}

Causer is the type of errors that can have a cause

type Code

type Code uint32

Code represents a unique error code

const NoCode Code = 0

NoCode is a missing code

func GetCode

func GetCode(err error) Code

GetCode infers the error code from the error

func (Code) String

func (c Code) String() string

String implmenents stringer

type ErrDescriptor

type ErrDescriptor struct {
	// MessageFormat is the format of the error message. Attributes will be filled
	// in when an error is created using New(). For example:
	//
	//   "This is an error about user {username}"
	//
	// when passed an atrtributes map with "username" set to "john" would interpolate to
	//
	//   "This is an error about user john"
	//
	// The idea about this message format is that is is localizable
	MessageFormat string

	// Code is the code of errors that are created by this descriptor
	Code Code

	// Type is the type of errors created by this descriptor
	Type Type
	// contains filtered or unexported fields
}

ErrDescriptor is a helper struct to easily build new Errors from and to be the authoritive information about error codes.

The descriptor can be used to find out information about the error after it has been handed over between components

func Descriptor

func Descriptor(in error) (desc *ErrDescriptor)

Descriptor returns the error descriptor from any error

func Get

func Get(code Code) *ErrDescriptor

Get returns an error descriptor based on an error code

func GetAll

func GetAll() []*ErrDescriptor

GetAll returns all registered error descriptors

func (*ErrDescriptor) New

func (err *ErrDescriptor) New(attributes Attributes) Error

New creates a new error based on the error descriptor

func (*ErrDescriptor) Register

func (err *ErrDescriptor) Register()

Register registers the descriptor

type Error

type Error interface {
	error

	// Code returns the error code
	Code() Code

	// Type returns the error type
	Type() Type

	// Attributes returns the error attributes
	Attributes() Attributes
}

Error is the interface of portable errors

func From

func From(in error) Error

From lifts an error to be and Error

func FromGRPC

func FromGRPC(in error) Error

FromGRPC parses a gRPC error and returns an Error

func FromHTTP

func FromHTTP(resp *http.Response) Error

FromHTTP parses the http.Response and returns the corresponding If the response is not an error (eg. 200 OK), it returns nil

func New

func New(descriptor *ErrDescriptor, attributes Attributes) Error

New creates a new Error from a descriptor and some attributes

type Type

type Type uint8

Type is the type of an error which, much like gRPC Codes or HTTP Status Codes, denotes what category an error belongs to and how to handle it.

const (
	// Unknown is the type of unknown or unexpected errors
	Unknown Type = iota

	// Internal is the type of internal errors
	Internal

	// InvalidArgument is the type of errors that result from an invalid argument
	// in a request
	InvalidArgument

	// OutOfRange is the type of errors that result from an out of range request
	OutOfRange

	// NotFound is the type of errors that result from an entity that is not found
	// or not accessible
	NotFound

	// Conflict is the type of errors that result from a conflict
	Conflict

	// AlreadyExists is the type of errors that result from a conflict where the
	// updated/created entity already exists
	AlreadyExists

	// Unauthorized is the type of errors where the request is unauthorized where
	// it should be
	Unauthorized

	// PermissionDenied is the type of errors where the request was authorized but
	// did not grant access to the requested entity
	PermissionDenied

	// Timeout is the type of errors that are a result of a process taking too
	// long to complete
	Timeout

	// NotImplemented is the type of errors that result from a requested action
	// that is not (yet) implemented
	NotImplemented

	// TemporarilyUnavailable is the type of errors that result from a service
	// being temporarily unavailable (down)
	TemporarilyUnavailable

	// PermanentlyUnavailable is the type of errors that result from an action
	// that has been deprecated and is no longer available
	PermanentlyUnavailable

	// Canceled indicates the operation was canceled (typically by the caller)
	Canceled

	// ResourceExhausted indicates some resource has been exhausted, perhaps
	// a per-user quota, or perhaps the entire file system is out of space.
	ResourceExhausted
)

func GRPCCodeToType

func GRPCCodeToType(code codes.Code) Type

GRPCCodeToType converts the gRPC error code to an error type or returns the Unknown type if not possible.

func GetType

func GetType(err error) Type

GetType infers the error type from the error or falls back to Unknown

func HTTPStatusToType

func HTTPStatusToType(status int) Type

HTTPStatusToType infers the error Type from a HTTP Status code

func (Type) GRPCCode

func (t Type) GRPCCode() codes.Code

GRPCCode returns the corresponding http status code from an error type

func (Type) HTTPStatusCode

func (t Type) HTTPStatusCode() int

HTTPStatusCode returns the corresponding http status code from an error type

func (Type) MarshalText

func (t Type) MarshalText() ([]byte, error)

MarshalText implements TextMarsheler

func (Type) String

func (t Type) String() string

String implements stringer

func (*Type) UnmarshalText

func (t *Type) UnmarshalText(text []byte) error

UnmarshalText implements TextUnmarsheler

Jump to

Keyboard shortcuts

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