errand is your little assistant for error slices or so-called multierrors. It helps you append multiple errors together into a single error as minimally as possible. The usage is as native as possible to the original error interface.
errand is the right library for you, if you just want a slice of actual errors from a bunch of calls. It gives you the following features:
- you can directly use errand - no need to initialize the error slice
- appending nil doesn't add another item to the slice - no need to check for nil before appending
- if the error you append to and append from is nil, the error is still nil - no need for a special method to get ErrOrNil() for your returns
- it doesn't force you that error is an error slice - returns that exact error if only one error was appended
- if any error is already an errand, only the entries are taken - exactly one level of error slice is returned, you are flexible in how you organize your code and where you return parts of your error slice
- no external dependencies - it doesn't add weight
errand is not a replacement for error wrapping. I encourage you to use golangs error wrapping functionality! As of now, you can't find out the types of these errors.
errand offers only one package exported function: Append
(besides the error and string interface type implementations Error
and String
).
To download errand:
go get github.com/dionysius/errand
To import errand:
import "github.com/dionysius/errand"
And use errand like you would with golangs append
:
package main
import (
"fmt"
"github.com/dionysius/errand"
)
func main() {
errs := fmt.Errorf("a function with possibly an error")
errs = errand.Append(errs, fmt.Errorf("directly add a possible error"))
// multiple errands are merged together, we get an errand from the separate function
errs = errand.Append(errs, separate())
// any nil errors are ignored
errs = errand.Append(errs, nil)
errs = errand.Append(errs, willBeNil())
// Output the error
fmt.Printf("%s\n", errs)
// Or we can also get the error slice using the Errors interface
if multi, is := errs.(errand.Errors); is {
for _, err := range multi.Errors() {
fmt.Println("->", err.Error())
}
}
}
func separate() error {
errs := errand.Append(nil, fmt.Errorf("you can directly use errand without initialisation of the first error"))
// If there is only one error, like the command above, errs will be exactly that error, not an errand error slice.
return errand.Append(errs, fmt.Errorf("and force that this function returns an errand since two errors were added"))
}
func willBeNil() error {
var err error
// If everything is nil, Append returns nil
return errand.Append(err, nil)
}
The output of the above example is (test it yourself with go run internal/readme.go
):
4 errors: a function with possibly an error, directly add a possible error, you can directly use errand without initialisation of the first error, and force that this function returns an errand since two errors were added
-> a function with possibly an error
-> directly add a possible error
-> you can directly use errand without initialisation of the first error
-> and force that this function returns an errand since two errors were added
- Implement the interfaces for
errors.Is
anderrors.As
. PRs welcome! - Not sure yet if I even want to: But we could offer an interface
Appends
to offer implementationsAppend(error, []error...)
so they can benefit from the merging of error slices into errand.
Most multierror packages are quite heavy. While they offer many features, It's often more than needed and that complicates their usage more than it should be. Don't get me wrong, they're definitely helpful and useful if you need those features!
errand is inspired by multierror from felixge. But since there are no licence informations, looks abandoned and misses a tiny little feature to append two error slices together, I've decided to create errand.