errm

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 11, 2024 License: MIT Imports: 5 Imported by: 2

README

errm

GoDoc Build GoReport

Package errm is wrapper on eris for convinient usage of errors with structrual fields and stack trace

Install: go get github.com/maxbolgarin/errm

Why you should try

There are familiar methods like New, Errorf, Wrap and others that works as expected. But there are two breaking futures:

  1. There is a stack trace in every error, thanks for the eris
  2. You can add field=value pairs to make an error message more convinient to handle in future

Which option is better for further search and analysis?

  • err1: cannot start server 'orders' at address: :7000: port is in use
  • err2: cannot start server=orders address=:7000: port is in use

The second one can be easily parsed and it is more friedly to read. Here is the code for these two examples:

err1 := fmt.Errorf("cannot start server '%s' at address: %s: %w", name, addr, err)
err2 := errm.Wrap(err, "cannot start", "server", name, "address", addr)

How to use

New error
err := errm.New("some-err", "field", "value", "field2", []any{123, 321}, "field3", 123, "field4")
fmt.Println(err) 

// some-err field=value field2=[123 321] field3=123
Wrap error
notFoundErr := errm.New("not found")

name := "database"
err2 := errm.Wrapf(err1, "another error with %s", name, "address", "127.0.0.1")

if errm.Is(err2, notFoundErr) {
    fmt.Println(err2)
}

// another error with database address=127.0.0.1: not found
Error List
randomErr := errm.Errorf("some random error with %s", "unwanted behaviour")
notFoundErr := errm.New("not found")

errList := errm.NewList()
errList.Add(randomErr)
errList.New("some error", "retry", 1)
errList.Wrap(notFoundErr, "database error")

if errList.Has(notFoundErr) {
    finalErr := errList.Err()
    fmt.Println(errm.Wrap(finalErr.Error(), "multi error")) 
}

// multi error: some random error with unwanted behaviour; some error retry=1; database error: not found
Error Set
errSet := errm.NewSet()

// Add the same error for three times
notFoundErr := errm.New("not found")
errSet.Add(notFoundErr)
errSet.Add(notFoundErr)
errSet.Add(notFoundErr)
fmt.Println(errSet.Len()) // 1

// Add two errors with the same message
errSet.Add(errm.New("A"))
errSet.Add(errm.New("A"))
fmt.Println(errSet.Len()) // 2

// Add an another error but with the same message
err := errors.New("A")
errSet.Add(err)
fmt.Println(errSet.Len()) // 2

// Add wrapped -> got another error message -> another error
errSet.Add(errm.Wrap(notFoundErr, "another error"))
fmt.Println(errSet.Len()) // 3

Contributing

If you'd like to contribute to errm, make a fork and submit a pull request!

Released under the MIT License

Documentation

Overview

Package errm is a library for convinient and easy use of errors in a golang code.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Check

func Check(err error) bool

Check returns true if the provided error is the one that was created using methods from this package.

func Contains

func Contains(err error, target string) bool

Contains reports whether any error in err's chain contains target string.

func ContainsErr

func ContainsErr(err, target error) bool

ContainsErr reports whether any error in err's chain contains target string representation.

func Errorf

func Errorf(msg string, args ...any) error

Errorf creates a new error with a formatted message and pairs of fields in a field=val format.

func Is

func Is(err, target error, targets ...error) bool

Is reports whether any error in err's chain matches target.

func JoinErrors

func JoinErrors(errs ...error) error

JoinErrors joins error messages using '; ' as separator (instead of '\n' like errors.Join() does).

a := errm.New("first error")
b := errm.New("second error")
JoinErrors(a, b)  // "first error; second error"

func New

func New(msg string, fields ...any) error

New creates a new error with a static message and pairs of fields in a field=val format.

func StackForLogger

func StackForLogger(err error) []any

StackForLogger returns slice ["stack", "[...]"] that can be used as fields for logger if you want to log stack trace.

func ToJSON

func ToJSON(err error) map[string]any

ToJSON returns a JSON formatted map for a given error.

func Wrap

func Wrap(err error, msg string, fields ...any) error

Wrap adds additional context to all error types while maintaining the type of the original error; It also adds pairs of fields in a field=val format to message.

func Wrapf

func Wrapf(err error, msg string, args ...any) error

Wrapf adds additional context to all error types while maintaining the type of the original error; It waits for formatted input and also adds pairs of fields in a field=val format to message.

Types

type List

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

List object is useful for collecting multiple errors into a single error, in which error messages are separated by a ";". This object is not safe for concurrent/parallel usage.

func NewList

func NewList() *List

NewList returns a new List instance with an empty underlying slice. Working with List will cause allocations, use NewListWithCapacity if you know the number of errors.

func NewListWithCapacity

func NewListWithCapacity(capacity int) *List

NewListWithCapacity returns a new List instance with an initialized underlying slice. It may be useful if you know the number of errors and you want to optimize code.

func (*List) Add

func (e *List) Add(err error)

Add appends an error to the underlying slice. It is noop if you provide an empty error.

func (*List) Clear

func (e *List) Clear()

Clear removes an underlying slice of errors.

func (*List) Empty

func (e *List) Empty() bool

Empty returns true if the List collector is empty.

func (*List) Err

func (e *List) Err() error

Err returns current List instance as error interface or nil if it is empty.

func (*List) Errorf

func (e *List) Errorf(format string, args ...any)

Errorf creates an error using Errorf and appends in to the underlying slice.

func (*List) Has

func (e *List) Has(err error, errs ...error) bool

Has returns true if the List contains the given error.

func (*List) Len

func (e *List) Len() int

Len returns the number of errors in List.

func (*List) New

func (e *List) New(err string, fields ...any)

New creates an error using New and appends in to the underlying slice.

func (*List) NotEmpty

func (e *List) NotEmpty() bool

NotEmpty returns true if the List collector has errors.

func (*List) Wrap

func (e *List) Wrap(err error, format string, fields ...any)

Wrap creates an error using Wrap and appends in to the underlying slice.

func (*List) Wrapf

func (e *List) Wrapf(err error, format string, args ...any)

Wrapf creates an error using Wrapf and appends in to the underlying slice.

type SafeList

type SafeList struct {
	List *List
	// contains filtered or unexported fields
}

SafeList object is useful for collecting multiple errors from different goroutines into a single error, in which error messages are separated by a ";". It is safe for concurrent/parallel usage.

func NewSafeList

func NewSafeList() *SafeList

NewSafeList returns a new SafeList instance with an empty underlying slice. Working with SafeList will cause allocations, use NewSafeListWithCapacity if you know the number of errors.

func NewSafeListWithCapacity

func NewSafeListWithCapacity(capacity int) *SafeList

NewSafeListWithCapacity returns a new SafeList instance with an initialized underlying slice. It may be useful if you know the number of errors and you want to optimize code.

func (*SafeList) Add

func (e *SafeList) Add(err error)

Add appends an error to the underlying slice. It is noop if you provide an empty error. It is safe for concurrent/parallel usage.

func (*SafeList) Clear

func (e *SafeList) Clear()

Clear removes underlying slice of errors. It is safe for concurrent/parallel usage.

func (*SafeList) Empty

func (e *SafeList) Empty() bool

Empty return true if the SafeList collector is empty. It is safe for concurrent/parallel usage.

func (*SafeList) Err

func (e *SafeList) Err() error

Err returns current SafeList instance as error interface or nil if it is empty. It is safe for concurrent/parallel usage.

func (*SafeList) Errorf

func (e *SafeList) Errorf(format string, args ...any)

Errorf creates an error using Errorf and appends in to the underlying slice. It is safe for concurrent/parallel usage.

func (*SafeList) Has

func (e *SafeList) Has(err error) bool

Has returns true if the SafeList contains the given error. It is safe for concurrent/parallel usage.

func (*SafeList) Len

func (e *SafeList) Len() int

Len returns the number of errors in SafeList. It is safe for concurrent/parallel usage.

func (*SafeList) New

func (e *SafeList) New(err string, fields ...any)

New creates an error using New and appends in to the underlying slice. It is safe for concurrent/parallel usage.

func (*SafeList) NotEmpty

func (e *SafeList) NotEmpty() bool

NotEmpty return true if the SafeList collector has errors. It is safe for concurrent/parallel usage.

func (*SafeList) Wrap

func (e *SafeList) Wrap(err error, format string, fields ...any)

Wrap creates an error using Wrap and appends in to the underlying slice. It is safe for concurrent/parallel usage.

func (*SafeList) Wrapf

func (e *SafeList) Wrapf(err error, format string, args ...any)

Wrapf creates an error using Wrapf and appends in to the underlying slice. It is safe for concurrent/parallel usage.

type SafeSet

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

SafeSet object is useful for collecting multiple unique errors from different goroutines into a single error, in which error messages are separated by a ";". It is safe for concurrent/parallel usage.

func NewSafeSet

func NewSafeSet() *SafeSet

NewSafeSet returns a new SafeSet instance with an empty underlying slice. Working with SafeSet will cause allocations, use NewSafeSetWithCapacity if you know the number of unique errors.

func NewSafeSetWithCapacity

func NewSafeSetWithCapacity(capacity int) *SafeSet

NewSafeSetWithCapacity returns a new SafeSet instance with an initialized underlying slice. It may be useful if you know the number of errors and you want to optimize code.

func (*SafeSet) Add

func (e *SafeSet) Add(err error)

Add sets an error to the underlying map. It is safe for concurrent/parallel usage.

func (*SafeSet) Clear

func (e *SafeSet) Clear()

Clear removes underlying map of errors. It is safe for concurrent/parallel usage.

func (*SafeSet) Empty

func (e *SafeSet) Empty() bool

Empty return true if the SafeSet collector is empty. It is safe for concurrent/parallel usage.

func (*SafeSet) Err

func (e *SafeSet) Err() error

Err returns current SafeSet instance as error interface or nil if it is empty. It is safe for concurrent/parallel usage.

func (*SafeSet) Errorf

func (e *SafeSet) Errorf(format string, args ...any)

Errorf creates an error using Errorf and sets in to the underlying map. It is safe for concurrent/parallel usage.

func (*SafeSet) Has

func (e *SafeSet) Has(err error) bool

Has returns true if the SafeSet contains the given error. It is safe for concurrent/parallel usage.

func (*SafeSet) Len

func (e *SafeSet) Len() int

Len returns the number of errors in SafeSet. It is safe for concurrent/parallel usage.

func (*SafeSet) New

func (e *SafeSet) New(err string, fields ...any)

New creates an error using New and sets it to the underlying map. It is safe for concurrent/parallel usage.

func (*SafeSet) Wrap

func (e *SafeSet) Wrap(err error, format string, fields ...any)

Wrap creates an error using Wrap and sets in to the underlying map. It is safe for concurrent/parallel usage.

func (*SafeSet) Wrapf

func (e *SafeSet) Wrapf(err error, format string, args ...any)

Wrapf creates an error using Wrapf and sets in to the underlying map. It is safe for concurrent/parallel usage.

type Set

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

Set object is useful for collecting multiple unique errors into a single error, in which error messages are separated by a ";". This object is not safe for concurrent/parallel usage. It is not very optimal thing, because it is calling err.Error() to make a key for the map. So you have time-overhead caused by Error() and space-overhead because it stores an error twice (string key and value). But you can win with it versus List when you have a lot of similar errors.

func NewSet

func NewSet() *Set

NewSet returns a new Set instance with an empty underlying map. Working with Set will cause allocations, use NewSetWithCapacity if you know the number of unique errors.

func NewSetWithCapacity

func NewSetWithCapacity(capacity int) *Set

NewSetWithCapacity returns a new Set instance with an initialized underlying map. It may be useful if you know the number of errors and you want to optimize code.

func (*Set) Add

func (e *Set) Add(err error)

Add sets an error to the underlying map. It is noop if you provide a nil error. It will call err.Error() to make a key for the map.

func (*Set) Clear

func (e *Set) Clear()

Clear removes an underlying map of errors.

func (*Set) Empty

func (e *Set) Empty() bool

Empty return true if the Set collector is empty.

func (*Set) Err

func (e *Set) Err() error

Err returns current Set instance as error interface or nil if it is empty.

func (*Set) Errorf

func (e *Set) Errorf(format string, args ...any)

Errorf creates an error using Errorf and sets in to the underlying map. It will call err.Error() to make a key for the map.

func (*Set) Has

func (e *Set) Has(err error, errs ...error) bool

Has returns true if the Set contains the given error.

func (*Set) Len

func (e *Set) Len() int

Len returns the number of errors in Set.

func (*Set) New

func (e *Set) New(msg string, fields ...any)

New creates an error using New and sets in to the underlying map. It will call err.Error() to make a key for the map.

func (*Set) Wrap

func (e *Set) Wrap(err error, format string, fields ...any)

Wrap creates an error using Wrap and sets in to the underlying map. It will call err.Error() to make a key for the map.

func (*Set) Wrapf

func (e *Set) Wrapf(err error, format string, args ...any)

Wrapf creates an error using Wrapf and sets in to the underlying map. It will call err.Error() to make a key for the map.

Jump to

Keyboard shortcuts

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