Doesn't the fact that errors are values, combined with the fact that you cannot ignore values (except explicitly by assigning them to "_"), provide compile time check for errors?
Doesn't the fact that errors are values, combined with the fact that you cannot ignore values (except explicitly by assigning them to "_"), provide compile time check for errors?
foo, err := foo()
if err != nil {
return nil, err
}
bar, err := bar(foo)
return bar, nil
The problem occurs because go only cares if a variable is used once per definition. Not once per assignment.Though I'd like to ask - does that scenario really happen in practice? It is idiomatic to handle every error right after the function call that returns the error. To me, the lack of "if err != nil {" under the "bar(foo)" call really stings my eyes.
I know, compile time checking is different from "it doesn't happen in practice". It's a tradeoff. I'm just wondering about the magnitude of the impact.
I've personally written something akin to the following, which triggered no errors (at the time, maybe this is fixed):
foo, err := foo()
if err != nil {
nil, err
}
return foo, nil
The worst part is because all of the error-handling is copypasta boilerplate, your eyes don't look at it. So subtle bugs get through and make it to production. I've seen this one too: foo, err := foo()
if err != nil {
return foo, nil
}
return foo, nil
Also note that now we've gone from "Doesn't [go] provide compile time check for errors?" to "Well I guess it doesn't check that errors are used, but that would never happen to me."True, but there was also a "you are right" in between :)
It does happen, I've seen it several times, and even other insidious examples that linters did not catch. When you're dealing with a code base that is constantly changes, things like that end up happening.
So if you assign 10 different error results to the same variable at various points, but only actually check it 9 times and forget the 10th, the compiler will not tell you that anything's wrong.
Perhaps variable re-declarations (via := operator) would be a good addition to Go. Compiler could optimize the code to re-use the variables when possible, but the semantics of the language would force the programmer to handle each and every error.