3 ms·
I use a similar pattern, cribbed from one of the Go databases that aspired never to ignore errors. The difference is that errs.Capture preserves existing errors
by sa46 2y ago
I use a similar pattern, cribbed from one of the Go databases that aspired never to ignore errors. The difference is that errs.Capture preserves existing errors and formats the error with a message--important if generalized to handle any error function.
package errs
// Capture runs errFunc and assigns the error, if any, to *errPtr. Preserves the
// original error by wrapping with errors.Join if the errFunc err is non-nil.
func Capture(errPtr *error, errFunc func() error, msg string) {
err := errFunc()
if err == nil {
return
}
*errPtr = errors.Join(*errPtr, fmt.Errorf("%s: %w", msg, err))
}
I conventionally use mErr to distinguish from err.
func doThing() (_ string, mErr error) {
f, err := os.Open("foo")
if err != nil {
return "", fmt.Errorf("open file: %w", err)
}
// Use the file...
defer errs.Capture(&mErr, f.Close, "close file")
return "", nil
}