Wandering Thoughts archives

2018-12-16

The Go 2 Error Handling proposal will likely lead to more use of error in return types

One of the bits of the Go 2 error handling proposal that some people dislike is that the new check keyword only works on values of type error. I've seen a number of suggestions in the wiki feedback page that widen this, making check more generally applicable. I don't have a strong opinion on this, but I do have an observation on the current approach.

One of my firm beliefs is that most programmers are strongly driven to do what their languages make easy. If a language makes something the easiest path to what programmers want, programmers will use that path, even if it's not what the path is really for and even if it requires some contortions. What the language designers feel about this or advocate doesn't really matter; people will not take the hard road just because you want them to and think they should.

In the current Go 2 error handling proposal, using a check on an error value is the easiest way to check for exceptional conditions. The obvious thing to expect here is that people will increasingly signal exceptional conditions through error values, including adding them to APIs where necessary or changing return values from other types (especially bool) to error instead. The resulting error may or may not be meaningful (in some cases it will be a boolean), but it can be used with check to make exception handling easy, and that's what a lot of people will care about.

(Some of these APIs will be public, but a lot more will be internal or even the informal 'APIs' of internal functions and methods inside a package.)

Whether or not this is a good thing probably depends on your perspective. On the one hand, we're likely to see a lot more use of error rather than people making up their own error mechanisms. On the other hand, some of those uses of error will not be for actual errors and the error values won't be particularly meaningful. Some of them will really be booleans, where the only thing that matters is whether the value is nil or non-nil. This risks confusing other people who expect the error values to have any meaning or use beyond the nil check used by check.

If people consider this change in error usage to be a bad thing, I don't think that there's any way out short of either not implementing error handling or of making check more general somehow.

(This is related to my views on the Go 2 error inspection proposal, where I also expect people to do what the proposal makes easiest, whether or not it's what the language designers want.)

Sidebar: A reason to keep check restricted to error values despite this

An error value is a clear signal that this is where you find whether or not something has succeeded (well, mostly, and CGo is an exception that is not really in normal Go APIs). This means that you can be very confident that checking an error for non-nil is a proper activity; you are not accidentally checking something that is not really an error signal. You can't have as much confidence in bool values or the like, and therefor there's a higher chance that programmers who are slapping check in front of functions that return bool are actually making a (tempting) mistake.

You might think that no one would ever make this sort of confusion. I disagree; exactly what is and isn't an error, and how they're signaled, is something that can easily go wrong if you're not working with something that is completely unambiguous. See, for example, how ZFS on Linux accidentally misunderstood an error return in a way that caused a kernel crash.

(In Go, a non-nil error value meaning an error is socially unambiguous, and it would become more so in a world with check in it. CGo is an unfortunate forced exception that I don't think anyone likes.)

programming/Go2ErrorHandlingHammer written at 00:57:21; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.