failure

package module
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: May 26, 2022 License: MIT Imports: 5 Imported by: 27

README

Failure

The failure package builds upon the errors package, implementing a strategy called Opaque errors which I first learned about from an article Don't just check errors handle them gracefully by Dave Cheney.

The failure package concentrates on an api that categories errors to better articulate your intent in code.

Usage

Server Failure

Describe general server errors. If I don't have a specific category for the error I use this. When mapping to http errors this would map to 500

System Failure

Means the same thing as Server but you prefer the name System instead. Note that you can not mix and match, meaning IsServer will not return true for a System

Startup

Is used to indicate failures that prevented the system from starting up

Shutdown

Is used to signal a shutdown of the system.

Defer

Categorize errors that originated inside a defer call

BadRequest

Categories errors that occurred because the accepted request was bad in some way

Validation

Describes an error that occurred because some validation failed

Config

Describes a failure caused by invalid configuration

InvalidParam

Describes a failure cause by a bad function param or struct field

NotAuthorized, NotAuthenticated, Forbidden

Describe auth errors

NotFound

Describes a failure due to the absence of a resource

Multiple

This is a direct port of hashicorp multierror. Many thanks to the hard work and great code produced my the hashicorp team. I integrated their code into this codebase to produce a seamless api when using multiple errors in the failure package.

NOTE: if you're using this package just because of multiple errors then I would use the hashicorps instead. I simply repurposed their code to fit into the failure system because I liked the way it reads.

The Append function is used to create a list of errors. This function behaves a lot like the Go built-in append function: it doesn't matter if the first argument is nil, a failure.Error, or any other error, the function behaves as you would expect.

var result error

if err := step1(); err != nil {
	result = failure.Append(result, err)
}
if err := step2(); err != nil {
	result = failure.Append(result, err)
}

return result
Customizing the formatting of the errors

By specifying a custom ErrorFormat, you can customize the format of the Error() string function:

var result *failure.Multi

// ... accumulate errors here, maybe using Append

if result != nil {
	result.Formatter = func([]error) string {
		return "errors!"
	}
}
Extracting an error
// Assume err is a failure value
err := somefunc()

if failure.IsMultiple(err) { 
	// It has it, and now errRich is populated.
}

var result []error

result, ok := failure.MultipleResult(err)
if ok {
	// Result will be []error in the failure.Multi
}


Timeout

Describes failures that occurred because something took too long

General Usage

  func(db *Client) Insert(ctx context.Context, model business.Model) error {
    ...

		if !db.Validatea(model) {
		  return failure.Validation("Model is not valid")	
		}
		
		out, err := db.api.Put(ctx, in)
		if err != nil {
			return failure.ToSystem(err, "db.api.Put failed for (%s)", in.ID)
		} 
		
		...
  }
	
	
func (h *Handler) Handle(ctx context.Context, w http.ResponseWrite, r http.Request) error {
		...
		if err = db.Insert(ctx, model); err != nil {
			switch {
			case: failure.IsValidation(err):
				// Return 400 
			default: 
				// return 500
			}
		}
	}

Documentation

Overview

Package failure implements an opaque error pattern based several of the most common types of errors that occur when developing microservices.

Index

Constants

View Source
const (
	SystemMsg             = "system failure"
	ServerMsg             = "server failure"
	NotFoundMsg           = "not found failure"
	NotAuthorizedMsg      = "not authorized failure"
	NotAuthenticatedMsg   = "not authenticated failure"
	ForbiddenMsg          = "access is forbidden"
	ValidationMsg         = "validation failure"
	DeferMsg              = "failure occurred inside defer"
	IgnoreMsg             = "ignore failure"
	ConfigMsg             = "config failure"
	InvalidParamMsg       = "invalid param failure"
	ShutdownMsg           = "system shutdown failure"
	TimeoutMsg            = "timeout failure"
	StartupMsg            = "failure occurred during startup"
	PanicMsg              = "panic"
	BadRequestMsg         = "bad request"
	InvalidAPIFieldsMsg   = "http input fields are not valid"
	MissingFromContextMsg = "resource not in context"
	AlreadyExistsMsg      = "duplicate resource already exists"
	OutOfRangeMsg         = "out of range failure"
	WarnMsg               = "warning"
	NoChangeMsg           = "no change has occurred"
	InvalidStateMsg       = "invalid state"
)

Variables

This section is empty.

Functions

func AlreadyExists added in v0.11.0

func AlreadyExists(format string, a ...interface{}) error

AlreadyExists is used to indicate that the given resource already exists

func BadRequest added in v0.6.0

func BadRequest(msg string, a ...interface{}) error

func Config added in v0.3.0

func Config(format string, a ...interface{}) error

Config is used to signify that error occurred when processing the application configuration

func Defer added in v0.2.0

func Defer(format string, a ...interface{}) error

Defer is used to signify errors that originate inside a defer function

func Flatten added in v0.9.0

func Flatten(err error) error

Flatten flattens the given error, merging any *Errors together into a single *Error.

func Forbidden added in v0.7.0

func Forbidden(format string, a ...interface{}) error

Forbidden is used to signify either not authenticated or not authorized

func GetInvalidFields added in v0.10.0

func GetInvalidFields(e error) (map[string]string, bool)

func Ignore

func Ignore(format string, a ...interface{}) error

Ignore is used to signify that error should not be acted on, it's up to the handler to decide to log these errors or not.

func InvalidFields added in v0.10.0

func InvalidFields(f map[string]string, msg string, a ...interface{}) error

func InvalidParam added in v0.4.0

func InvalidParam(format string, a ...interface{}) error

InvalidParam is to indicate that the param of a function or any parameter in general is invalid

func InvalidState added in v0.14.0

func InvalidState(format string, a ...interface{}) error

InvalidState is used to signal that the resource is not in a valid state

func IsAlreadyExists added in v0.11.0

func IsAlreadyExists(e error) bool

func IsAnyAuthFailure added in v0.7.0

func IsAnyAuthFailure(e error) bool

IsAnyAuthFailure can be used to determine if any of the following we used: NotAuthenticated, NotAuthorized, Forbidden

func IsBadRequest added in v0.6.0

func IsBadRequest(e error) bool

func IsConfig added in v0.3.0

func IsConfig(e error) bool

func IsDefer added in v0.2.0

func IsDefer(e error) bool

func IsForbidden added in v0.7.0

func IsForbidden(e error) bool

func IsIgnore

func IsIgnore(e error) bool

func IsInvalidFields added in v0.10.0

func IsInvalidFields(e error) bool

func IsInvalidParam added in v0.4.0

func IsInvalidParam(e error) bool

func IsInvalidState added in v0.14.0

func IsInvalidState(e error) bool

func IsMissingFromContext added in v0.11.0

func IsMissingFromContext(e error) bool

func IsMultiple added in v0.9.0

func IsMultiple(e error) bool

func IsNoChange added in v0.13.0

func IsNoChange(e error) bool

func IsNotAuthenticated added in v0.7.0

func IsNotAuthenticated(e error) bool

func IsNotAuthorized added in v0.7.0

func IsNotAuthorized(e error) bool

func IsNotFound

func IsNotFound(e error) bool

func IsOutOfRange added in v0.12.0

func IsOutOfRange(e error) bool

func IsPanic added in v0.10.0

func IsPanic(e error) bool

func IsRestAPI added in v0.10.0

func IsRestAPI(e error) bool

func IsServer

func IsServer(err error) bool

IsServer will return true if the cause is a serverErr

func IsShutdown added in v0.5.0

func IsShutdown(e error) bool

func IsStartup added in v0.9.0

func IsStartup(e error) bool

func IsSystem

func IsSystem(err error) bool

func IsTimeout added in v0.8.0

func IsTimeout(e error) bool

func IsValidation

func IsValidation(e error) bool

func IsWarn added in v0.13.0

func IsWarn(e error) bool

func ListFormatFn added in v0.9.0

func ListFormatFn(es []error) string

ListFormatFn is a basic formatter that outputs the number of errors that occurred along with a bullet point list of the errors.

func MissingFromContext added in v0.11.0

func MissingFromContext(format string, a ...interface{}) error

MissingFromContext is used to indicate a resource was supposed to be in the context but is missing

func MultiResult added in v0.9.0

func MultiResult(e error) ([]error, bool)

func NoChange added in v0.13.0

func NoChange(format string, a ...interface{}) error

NoChange is used to signal that if you expected something to change, it has not.

func NotAuthenticated added in v0.7.0

func NotAuthenticated(format string, a ...interface{}) error

NotAuthenticated is used to signify that a resource's identity verification failed. They are not who they claim to be

func NotAuthorized added in v0.7.0

func NotAuthorized(format string, a ...interface{}) error

NotAuthorized is used to signify that a resource does not have sufficient access to perform a given task

func NotFound

func NotFound(format string, a ...interface{}) error

NotFound is used to signify that whatever resource you were looking for does not exist and that fact it does not exist is an error.

func OutOfRange added in v0.12.0

func OutOfRange(format string, a ...interface{}) error

OutOfRange is used to signal that the offset of a map is invalid or some index for a list is incorrect

func Panic added in v0.10.0

func Panic(format string, a ...interface{}) error

Panic is used in panic recovery blocks or to indicate that you should panic if you receive this error

func RestError added in v0.10.0

func RestError(e error) (error, bool)

func RestMessage added in v0.10.0

func RestMessage(e error) (string, bool)

func RestStatusCode added in v0.10.0

func RestStatusCode(e error) (int, bool)

func Server

func Server(format string, a ...interface{}) error

Server has the same meaning as Platform or System, it can be used instead if you don't like how Platform or System reads in your code.

func Shutdown added in v0.5.0

func Shutdown(format string, a ...interface{}) error

Shutdown is used to signal that the app should shut down.

func Startup added in v0.9.0

func Startup(format string, a ...interface{}) error

Startup is used to signify a failure preventing the system from starting up

func System

func System(format string, a ...interface{}) error

System is has the same meaning as Platform or Server, it can be used instead if you don't like how Platform reads in your code

func Timeout added in v0.8.0

func Timeout(format string, a ...interface{}) error

Timeout is used to signify that error because something was taking too long

func ToAlreadyExists added in v0.11.0

func ToAlreadyExists(e error, format string, a ...interface{}) error

func ToBadRequest added in v0.6.0

func ToBadRequest(e error, msg string, a ...interface{}) error

func ToConfig added in v0.3.0

func ToConfig(e error, format string, a ...interface{}) error

func ToDefer added in v0.2.0

func ToDefer(e error, format string, a ...interface{}) error

func ToForbidden added in v0.7.0

func ToForbidden(e error, format string, a ...interface{}) error

func ToIgnore

func ToIgnore(e error, format string, a ...interface{}) error

ToIgnore converts `e` into the root cause of ignoreErr, it informs the system to ignore error. Used typically to log results and do not act on the error itself.

func ToInvalidParam added in v0.4.0

func ToInvalidParam(e error, format string, a ...interface{}) error

func ToInvalidState added in v0.14.0

func ToInvalidState(e error, format string, a ...interface{}) error

func ToMissingFromContext added in v0.11.0

func ToMissingFromContext(e error, format string, a ...interface{}) error

func ToNoChange added in v0.13.0

func ToNoChange(e error, format string, a ...interface{}) error

func ToNotAuthenticated added in v0.7.0

func ToNotAuthenticated(e error, format string, a ...interface{}) error

func ToNotAuthorized added in v0.7.0

func ToNotAuthorized(e error, format string, a ...interface{}) error

func ToNotFound

func ToNotFound(e error, format string, a ...interface{}) error

func ToOutOfRange added in v0.12.0

func ToOutOfRange(e error, format string, a ...interface{}) error

func ToPanic added in v0.10.0

func ToPanic(e error, format string, a ...interface{}) error

func ToServer

func ToServer(e error, format string, a ...interface{}) error

func ToShutdown added in v0.5.0

func ToShutdown(e error, format string, a ...interface{}) error

func ToStartup added in v0.9.0

func ToStartup(e error, format string, a ...interface{}) error

func ToSystem

func ToSystem(e error, format string, a ...interface{}) error

func ToTimeout added in v0.8.0

func ToTimeout(e error, format string, a ...interface{}) error

func ToValidation

func ToValidation(e error, format string, a ...interface{}) error

func ToWarn added in v0.13.0

func ToWarn(e error, format string, a ...interface{}) error

func Validation

func Validation(format string, a ...interface{}) error

Validation is used to signify that a validation rule as been violated

func Warn added in v0.13.0

func Warn(format string, a ...interface{}) error

Warn is used to signal that this error is only a warning. It can be used instead of ignore to change the log level of a system

func Wrap

func Wrap(err error, msg string, a ...interface{}) error

Wrap expose errors.Wrapf as our default wrapping style

Types

type Group added in v0.9.0

type Group struct {
	// contains filtered or unexported fields
}

Group is a collection of goroutines which return errors that need to be coalesced.

func (*Group) Go added in v0.9.0

func (g *Group) Go(f func() error)

Go calls the given function in a new goroutine.

If the function returns an error it is added to the group multierror which is returned by Wait.

func (*Group) Wait added in v0.9.0

func (g *Group) Wait() *Multi

Wait blocks until all function calls from the Go method have returned, then returns the Multi

type Multi added in v0.9.0

type Multi struct {
	Failures  []error
	Formatter MultiFormatFn
}

func Append added in v0.9.0

func Append(err error, errs ...error) *Multi

func Multiple added in v0.9.0

func Multiple(errs []error, opt ...MultiFormatFn) *Multi

func (*Multi) Error added in v0.9.0

func (e *Multi) Error() string

func (*Multi) ErrorOrNil added in v0.9.0

func (e *Multi) ErrorOrNil() error

ErrorOrNil returns an error interface if this Error represents a list of errors, or returns nil if the list of errors is empty. This function is useful at the end of accumulation to make sure that the value returned represents the existence of errors.

func (Multi) Len added in v0.9.0

func (e Multi) Len() int

Len implements sort.Interface function for length

func (Multi) Less added in v0.9.0

func (e Multi) Less(i, j int) bool

Less implements sort.Interface function for determining order

func (Multi) Swap added in v0.9.0

func (e Multi) Swap(i, j int)

Swap implements sort.Interface function for swapping elements

func (*Multi) Unwrap added in v0.9.0

func (e *Multi) Unwrap() error

Unwrap returns an error from Multi (or nil if there are no errors). This error returned will further support Unwrap to get the next error, etc. The order will match the order of Errors in the failure.Multi at the time of calling.

The resulting error supports errors.As/Is/Unwrap, so you can continue to use the stdlib errors package to introspect further.

This will perform a shallow copy of the errors slice. Any errors appended to this error after calling Unwrap will not be available until a new Unwrap is called on the failure.Multi.

func (*Multi) WrappedErrors added in v0.9.0

func (e *Multi) WrappedErrors() []error

WrappedErrors returns the list of errors that this Error is wrapping. It is an implementation of the errwrap.Wrapper interface so that failure.Multi can be used with that library.

This method is not safe to be called concurrently. Unlike accessing the Failures field directly, this function also checks if the Multi is nil to prevent a null-pointer panic. It satisfies the errwrap.Wrapper interface.

type MultiFormatFn added in v0.9.0

type MultiFormatFn func([]error) string

type RestAPI added in v0.10.0

type RestAPI struct {
	StatusCode int
	Msg        string
	Fields     map[string]string
	Err        error
}

func NewBadRequest added in v0.10.0

func NewBadRequest(msg string, a ...interface{}) *RestAPI

func NewInvalidFields added in v0.10.0

func NewInvalidFields(f map[string]string, msg string, a ...interface{}) *RestAPI

func (*RestAPI) Error added in v0.10.0

func (r *RestAPI) Error() string

Jump to

Keyboard shortcuts

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