diff --git a/error.go b/error.go index 5c2c9e1..cdd91ae 100644 --- a/error.go +++ b/error.go @@ -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)) +} diff --git a/error_test.go b/error_test.go index c053167..39ca313 100644 --- a/error_test.go +++ b/error_test.go @@ -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 }