Typically in Go you find the following convention:
res, err := thingThatCanError(arg)
if err != nil {
// handle it
}
However, it's obvious this gets VERY unruly very quickly for a large number of these calls:
res, err := thingThatCanError(arg)
if err != nil {
// handle it
}
res, err2 := thingThatCanError(arg)
if err2 != nil {
// handle it
}
res, err3 := thingThatCanError(arg)
if err3 != nil {
// handle it
}
There's more lines of boilerplate error handling than code! This website says to avoid this but does not give an example on how to clean up this smell. A useful example comes straight from the Go blog that shows us how to clean up a homogenous HTTP app with an error handler that makes sense.
But imagine each of these calls aren't homogenous, as in with the same "central idea", so a single "error handler struct" wouldn't make a lot of sense.
Is there a way to clean up this type of code smell with functions that don't "mesh together" nicely in terms of errors?
Unfortunately there's sometimes no way around these patterns. You could use panic/defer as a makeshift try/catch system but the community looks down upon it.
If statements in Go can be combined with assignments so
err := thing.Do()
if err != nil {
return err
}
can become
if err := thing.Do(); err != nil {
return err
}