What is the most idiomatic way to handle multiple errors in go?
Should I try to wrap the error and return both?
if err := foo(bar, obj); err != nil {
// how to do I avoid losing this error?
err := l.fixup(obj)
if err != nil {
// but this error is the not the one from foo?
}
return err
}
return l.fixup(obj)
You can add a context to your original error using Wrap function from this great package from Dave Cheney
https://github.com/pkg/errors
errors.Wrap function returns a new error that adds context to the original error.
func Wrap(cause error, message string) error
in your case this would be:
if cause := foo(bar, obj); cause != nil {
err := l.fixup(obj)
if err != nil {
return errors.Wrap(cause, err.Error())
}
return cause
}
return l.fixup(obj)
If you must chain errors and return, it all depends what your error means and which one you want to notify the caller of. Usually, when the occurence of an error should not stop the path and a call follows, such as foo here then fixup, you'd log the first error and return the second one, as it is probably the most relevant to what your function does.
There are also packages to wrap errors, so that you can build an error from multiple errors.
There is the standard package with fmt.Errorf you could assemble multiple errors.
There is also https://github.com/hashicorp/go-multierror which allows you to keep multiple errors in an error.
In your case, if you want to get both error messages to bubble up, I'd do something like that:
err := foo(bar, obj)
if fixupErr := l.fixup(obj); fixupErr != nil {
if err != nil {
return fmt.Errorf("foo err: %s\nfixup err: %s\n", err, fixupErr)
}
return fixupErr
}
return err
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With