maperr

package module
v4.3.5 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2021 License: Apache-2.0 Imports: 4 Imported by: 0

README

maperr

maperr is a library that allow you to define a list of errors which you want to map to some other errors.

Motivation

When writing a service which adopts a multi-layer architecture (e.g.: presentation, domain and storage) errors which are returned in lower layers of the application are often wrapped with other errors. This not only add context but also allow you to assertion in your higher layer (e.g.: presentation) without having to directly perform checks for errors which are held withing the lower layers of your application (e.g.: storage).

This works fine if all your error will be mapped to a 5xx error. However, sometimes some of this error are more user errors which have been detected lower down the application layers which could fall in the 4xx range.

This requires a mapping of errors, between layers, and if you have many errors to map, you would end up with one if statement for each error. This library allow you to handle all of them in a single if statement.

Mapping errors to status code

var errMapper = maperr.NewMultiErr(
	maperr.NewListMapper().
		Append(domain.ErrOne, maperr.WithStatus("err one happened", http.StatusInternalServerError)).
		Append(domain.ErrTwo, maperr.WithStatus("err two happened", http.StatusBadRequest)).
		Append(domain.ErrThree, maperr.WithStatus("err three happened", http.StatusConflict)).
		Append(domain.ErrDeadlineExceeded, maperr.WithStatus("deadline exceeded", http.StatusBadRequest)).
		Append(domain.ErrCanceled, maperr.WithStatus("context was cancelled", http.StatusBadRequest)),
    
	maperr.NewIgnoreListMapper().
        Append(domain.ErrThatNeedsIgnored),
)

func (h Handler) Update(rw http.ResponseWriter, r *http.Request) {
    ...
    entity, err := h.Controller.Update(r.Context(), id)
    if mappedErr := errMapper.MappedWithStatus(err, maperr.WithStatusInternalServerError); mappedErr != nil {
    	 // mappedErr.Error() -> error to send in response
         // mappedErr.Status() -> status code for response
         // mappedErr.Unwrap() -> cause to log
    }
Mapping errors to other errors
    var errMapper = maperr.NewMultiErr(
        maperr.NewHashableMapper()
            Append(storage.ErrOne, ErrOne).
            Append(storage.ErrTwo, ErrTwo).
            Append(storage.ErrThree, ErrThree).
            Append(context.DeadlineExceeded, ErrDeadlineExceeded).
            Append(context.Canceled, ErrCanceled).
            Append(sql.ErrNoRows, ErrorUserNotFound))

    func (c Controller) Update(ctx context.Context, user User) error {
        ...
        err := s.storage.Update(user)
        if appendedErr := errMapper.Mapped(err, ErrSomethingBadHappened); appendedErr != nil {
            return appendedErr
        }
    }

Documentation

Index

Constants

This section is empty.

Variables

Default error with statuses

Functions

func Append

func Append(left, right error) error

Append appends the given errors together. Either value may be nil.

func Combine

func Combine(errList ...error) error

Combine combines the passed errors into a single error.

func HasError

func HasError(err error, errText string) bool

HasError checks if an error has been wrapped

func LastAppended

func LastAppended(err error) error

LastAppended return the lastErr error appended as multierr

func WithStatus

func WithStatus(err string, status int) error

WithStatus return an error with an associated status

Types

type Error

type Error interface {
	error
	Equal(error) bool
	Hashable() error
	Is(err error) bool
}

Error which exposes a method that determines if the error can be considered equal or not

func Errorf

func Errorf(format string, args ...interface{}) Error

Errorf returns an error which persists

func HasEqual

func HasEqual(chain, err error) Error

HasEqual find the first equal error on a chain of errors and returns it

func NewError

func NewError(errText string) Error

NewError instantiates an Error with no formatting

type ErrorWithStatusProvider

type ErrorWithStatusProvider interface {
	error
	Status() int
	Unwrap() error
}

ErrorWithStatusProvider defines an error which also has an http status defined

type HashableMapper

type HashableMapper map[error]error

HashableMapper simple implementation of Mapper which only works on hashable error keys

func NewHashableMapper

func NewHashableMapper() HashableMapper

NewHashableMapper make a new instance of HashableMapper

func (HashableMapper) Append

func (hm HashableMapper) Append(err, match error) HashableMapper

Append append an error to error association

type IgnoreListMapper

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

IgnoreListMapper is a Mapper that allow to specify a list of error that we want to ignore

func NewIgnoreListMapper

func NewIgnoreListMapper() IgnoreListMapper

NewIgnoreListMapper create an instance of IgnoreListMapper

func (IgnoreListMapper) Append

func (lm IgnoreListMapper) Append(err error) IgnoreListMapper

Append appends an error that we want to ignore

func (IgnoreListMapper) Appendf

func (lm IgnoreListMapper) Appendf(format string) IgnoreListMapper

Appendf appends a formatted error that we want to ignore

type ListMapper

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

ListMapper maps not hashable or formatted errorPairs

func NewListMapper

func NewListMapper() ListMapper

NewListMapper return a new ListMapper

func (ListMapper) Append

func (lm ListMapper) Append(err, match error) ListMapper

Append append an error to error association

func (ListMapper) Appendf

func (lm ListMapper) Appendf(format string, match error) ListMapper

Appendf append a format to error association

type Mapper

type Mapper interface {
	// contains filtered or unexported methods
}

Mapper takes an error and return a mapResult

type MultiErr

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

MultiErr an error to another error

func NewMultiErr

func NewMultiErr(mapper ...Mapper) MultiErr

NewMultiErr return a new instance of MultiErr

func (MultiErr) LastMappedWithStatus

func (m MultiErr) LastMappedWithStatus(err error) ErrorWithStatusProvider

LastMappedWithStatus return the lastErr mapped error with the associated http status Deprecated: consider using MappedWithStatus() instead, as encourages to specify a default error

func (MultiErr) Mapped

func (m MultiErr) Mapped(err, defaultErr error) error

Mapped appends the mapped error or a default one when is not found

func (MultiErr) MappedWithStatus

func (m MultiErr) MappedWithStatus(err, defaultErr error) ErrorWithStatusProvider

MappedWithStatus return the lastErr mapped error with the associated http status You can optionally provide a default error in case that will be returned if the error has not been mapped

defaultErr == nil returns the ErrorWithStatusProvider only if error is mapped

alias for LastMappedWithStatus(err)

defaultErr.(ErrorWithStatusProvider) allow you to specify a status code

e.g.: maperr.WithStatus("USER_ERROR", http.StatusBadRequest)

defaultErr.(error) will cast to a ErrorWithStatusProvider with http.StatusInternalServerError

type PairErrors

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

PairErrors holds a pair of errorPairs

Jump to

Keyboard shortcuts

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