Hi,
I often write code like the the function below but this style can make the
simplest functions hard to read because the actual logic is drowned in
error handling. Is there a better pattern that separates the error handling
from the logic so that the logic is more readable?
func doStuff(context Context) (err error) {
x, err := computeX()
if err != nil {
context.Errorf("Error computing x: %v", err)
return
}
err = doSomethingWithX(x)
if err != nil {
context.Errorf("Error doing something: %v", err)
}
return
}
If I wouldn't have to do error handling, the code could look like this
which is actually readable:
func doStuff() (err error) {
x := computeX()
doSomethingWithX(x)
}
This gives me the impression I must be doing something wrong, but what?
Should I do something like this?
func computeX(context Context, err *error) (x X) {
x, *err = reallyComputeX()
if *err != nil {
context.Errorf("Error computing x: %v", err)
}
return
}
func doSomethingWithX(x X, context Context, err *error) {
if *err != nil { return }
err = reallyDoSomething(x)
if *err != nil {
context.Errorf("Error doing something: %v", err)
}
}
func doStuff(context Context) (err error) {
x := computeX(context, &err)
doSomethingWithX(x, context, &err)
}
This is more readable (to me) but it feels very silly to call
doSomethingWithX even if computeX failed, only to return immediately
because err was already != nil.
Any other suggestions?
Thanks,
David
--