Skip to content

Commit

Permalink
Add a shorthand for AppendInvoke (#65)
Browse files Browse the repository at this point in the history
I really like the idea of catching returned errors from deferred functions. Though having to use `multierr` package name twice in the same line makes it a bit verbose in many occasions.

This PR introduces a shorthand for AppendInvoke which allows passing function or method value directly without wrapping it into an Invoker.

So this:

```go
defer multierr.AppendInvoke(&err, multierr.Invoke(my.StopFunc))
```

could become this:

```go
defer multierr.AppendFunc(&err, my.StopFunc)
```

Co-authored-by: Sung Yoon Whang <sungyoonwhang@gmail.com>
  • Loading branch information
burdiyan and sywhang committed Sep 6, 2022
1 parent 80b07a7 commit 4459990
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
19 changes: 19 additions & 0 deletions error.go
Expand Up @@ -660,3 +660,22 @@ func Close(closer io.Closer) Invoker {
func AppendInvoke(into *error, invoker Invoker) {
AppendInto(into, invoker.Invoke())
}

// AppendFunc is a shorthand for [AppendInvoke].
// It allows using function or method value directly
// without having to wrap it into an [Invoker] interface.
//
// func doSomething(...) (err error) {
// w, err := startWorker(...)
// if err != nil {
// return err
// }
//
// // multierr will call w.Stop() when this function returns and
// // if the operation fails, it appends its error into the
// // returned error.
// defer multierr.AppendFunc(&err, w.Stop)
// }
func AppendFunc(into *error, fn func() error) {
AppendInvoke(into, Invoke(fn))
}
18 changes: 18 additions & 0 deletions error_test.go
Expand Up @@ -675,6 +675,24 @@ func TestAppendIntoNil(t *testing.T) {
})
}

func TestAppendFunc(t *testing.T) {
var (
errDeferred = errors.New("deferred func called")
errOriginal = errors.New("original error")
)

stopFunc := func() error {
return errDeferred
}

err := func() (err error) {
defer AppendFunc(&err, stopFunc)

return errOriginal
}()
assert.Equal(t, []error{errOriginal, errDeferred}, Errors(err), "both deferred and original error must be returned")
}

func errorPtr(err error) *error {
return &err
}
Expand Down

0 comments on commit 4459990

Please sign in to comment.