https://github.com/justindfuller/go-multierror
Combine Errors in Go
https://github.com/justindfuller/go-multierror
error errors go golang multierror
Last synced: 8 months ago
JSON representation
Combine Errors in Go
- Host: GitHub
- URL: https://github.com/justindfuller/go-multierror
- Owner: JustinDFuller
- License: gpl-3.0
- Created: 2023-02-17T02:32:39.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2023-02-18T21:43:17.000Z (almost 3 years ago)
- Last Synced: 2025-05-07T21:57:15.323Z (8 months ago)
- Topics: error, errors, go, golang, multierror
- Language: Go
- Homepage:
- Size: 57.6 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# go-multierror
[](https://pkg.go.dev/github.com/justindfuller/go-multierror)
[](https://github.com/JustinDFuller/go-multierror/actions/workflows/build.yml)
[](/go.mod)
[](https://goreportcard.com/report/github.com/justindfuller/go-multierror)
[](/LICENSE)

Package multierror implements a `Join` function that combines two or more Go errors.
```
go get github.com/justindfuller/go-multierror
```
## Examples
Joining two errors:
```go
func main() {
err1 := errors.New("my first error")
err2 := errors.New("my second error")
err := multierror.Join(err1, err2)
fmt.Println(err)
// Found 2 errors:
// my first error
// my second error
}
```
Joining nil errors will result in `nil` so that you don't have to do extra `nil` checks before joining:
```go
func main() {
err := multierror.Join(nil, nil, nil)
fmt.Println(err)
//
}
```
## Supported Interfaces
The resulting errors support many common Go interfaces.
* error
* Stringer
* Marshaler
* GoStringer
* GobEncoder
* BinaryMarshaler
* TextMarshaler
```go
func main() {
err1 := errors.New("something bad happened")
err2 := errors.New("something is broken")
err := multierror.Join(err1, err2)
b, _ := json.Marshal(err)
fmt.Println(string(b))
// output: "something bad happened, something is broken"
}
```
They also support common Go error methods.
* errors.Is
* errors.As
* errors.Unwrap
errors.Is:
```go
func main() {
err1 := errors.New("something bad happened")
err2 := errors.New("something is broken")
err3 := errors.New("something is REALLY broken")
err := multierror.Join(err1, err2)
err = multierror.Join(err, err3)
fmt.Println(errors.Is(err, err1))
// output: true
}
```
errors.As:
```go
func main() {
_, err := os.Open("non-existing")
if err == nil {
fmt.Println("No error")
}
err = multierror.Join(err, errSentinelOne)
var pathError *fs.PathError
fmt.Println(errors.As(err, &pathError))
// output: true
}
```
## Why?
I've been unhappy with existing `go-multierror` implementations.
There are three that I am aware of:
1. The standard library [errors.Join](https://pkg.go.dev/errors#Join)
2. Hashicorp's [go-multierror](https://github.com/hashicorp/go-multierror)
3. Uber's [go-multierr](https://github.com/uber-go/multierr)
These libraries have the following problems (in no particular order, not all problems apply to all of them):
* They do not implement common interfaces such as Marshaler, so they don't work with JSON output. This applies to other interfaces and encoders as well.
* They all have different interfaces and methods.
* They expose their underlying error type.
* They import third-party dependencies
This `go-multierror` solves these problems by:
* Implementing common interfaces (listed above).
* Aligning the interface with the Go standard library.
* Hiding the underlying error type.
* Using only standard library dependencies