3 ms·
Some other variants I've played with: func foo() (err error) { var x any if x, err = bar(); err != nil { goto fooError } if err = baz(x
by dpifke 3y ago
Some other variants I've played with:
func foo() (err error) {
var x any
if x, err = bar(); err != nil {
goto fooError
}
if err = baz(x); err != nil {
goto fooError
}
if err = bat(); err != nil {
goto fooError
}
return
fooError:
return fmt.Errorf("%w doing foo <additional info here>", err)
}
Or:
func foo() (err error) {
defer func() {
if err != nil {
err = fmt.Errorf("%w doing foo <additional info here>", err)
}
}()
var x any
if x, err = bar(); err != nil {
return
}
if err = baz(x); err != nil {
return
}
err = bat()
return
}
Seeking out different patterns is obviously most applicable in cases where error handling is actually doing something useful or more complicated than just wrapping the error.
(My comment was meant to spur first principles discussion from intellectually curious folks, not "nobody does it that way" or "don't do that" edicts. Much of the argument against adding additional language features for error handling is that many of them aren't any better than what can be accomplished already, using existing syntax but different code style conventions. The goto pattern in particular is found all over the stdlib.)
- euroderf 3y agoI like your second variant - some DRY, moved to the top of the function. This would reduce fiddling during preliminary development, with loggers and Printf's and whatevers, until an error architecture stabilizes.
- preseinger 3y ago> The goto pattern in particular is found all over the stdlib. in generated code, sure -- that's why it exists, to support codegen it's sometimes abused to manage for loop control flow but the stdlib is definitely not some platonic ideal -- it's a decade+ old code base which has suffered all of the indignities of organic growth it's full of bad code and terrible anti-patterns (good stuff, too!)