Skip to content

Go errors with structural fields and stack trace

License

Notifications You must be signed in to change notification settings

maxbolgarin/errm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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