At the end of quite a long public discussion, the Go team decided to reject the proposal of a built-in try
statement for Go error handling. The decision came ahead of the official Go 2 schedule due to the Go community's negative reaction, writes Robert Griesemer, one of the original designers of the language.
As Google engineer Russ Cox recalled in his response to an open letter about try
, error handling has consistently been one of the top pain points for Go users for a number of years. Consequently, the Go team started working on it with the goal to overhaul error handling in Go 2, as Griesemer explains, but only to find out the overall Go community was not ready for the change:
We have just dedicated quite a bit of time and energy on this over the last half year and especially the last 3 months, and we were quite happy with the proposal, yet we have obviously underestimated the possible reaction towards it. Now it does make a lot of sense to step back, digest and distill the feedback, and then decide on the best next steps.
The reason why Go error handling is considered a pain point by many Go developers is its requirement to explicitly handle errors when calling a function by forcing too much boilerplate on the developer, as you can see in the following example:
value, err := DoSomething()
if err != nil {
log.Println(err)
return err
}
This is considered tedious and in itself error prone, for example for the possibility of inverting the check using if error == nil
, which can lead to subtle errors in code reviews. In addition, the readability of the code is affected even more when developers follow the best practice of decorating errors with some context-local information before returning them back.
All of this led to the now-rejected try
proposal, which, in its final form, introduced a try
statement to wrap calls to functions that may fail and an additional defer
statement to be used to propagate context information:
f := try(os.Open(filename))
...
// err is the name of the error result of the enclosing function
defer func() {
if err != nil { // no error may have occurred - check for it
err = … // wrap/augment error
}
}()
Criticism to this proposal included reducing explicitness of return
points in exchange for less code repetitition; the need to use a named error variable when using defer
; more complex debugging to add debug-only if
statements; and more complex code coverage analysis. An additional concern that was raised highlighted the fact that while it was true that error handling was among the top Go issues in many surveys, this was due to a mere 5% of surveyed developers. All of this made the Go team backtrack on their proposal and leave work on error handling for a later moment:
Google is not stopping work on this and accepts feedback to what parts of error handling are more cumbersome.
On the good side of things, Russ Cox pointed out the community-wide discussion about try
was open source at its best, in spite of the final outcome being a rejection.
If you want, you can leave your feedback to provide the Go team with more detailed and varied opinions on the matter.
Community comments
Dodged a bullet
by Cameron Purdy,
Glad they didn't rush exception support
by Gordon Milne,
Dodged a bullet
by Cameron Purdy,
Your message is awaiting moderation. Thank you for participating in the discussion.
Glad to see that Google didn't jam that flustercluck through.
I must admit that I like the "try-as-an-expression" concept itself, though; it could clean up common exception use cases where a variable (one or more) has to be declared in advance of the try block, and is only definitely assigned by the successful completion of the block.
Glad they didn't rush exception support
by Gordon Milne,
Your message is awaiting moderation. Thank you for participating in the discussion.
I am glad they are taking time to think this through a bit further.
The example shown above whereby a failure opening a file was handled as an exception is (in my opinion) an example of exactly the wrong place to use an exception. It isn't exceptional for a file open to fail. The access permission could be wrong, the file name may be incorrect, etc. These are not exceptional conditions and should not be treated as such.
This 2003 article by Joel Spolsky is a short read about exceptions in your code. When he wrote the article he didn't have access to a langue like Go that let functions return multiple values, including error state. Things have got better.