proposal: Error handling: error-specific type switch #70169
Labels
error-handling
Language & library change proposals that are about error handling.
LanguageChange
Suggested changes to the Go language
LanguageChangeReview
Discussed by language change review committee
Proposal
Milestone
Go Programming Experience
Intermediate
Other Languages Experience
JS, C#, Java
Related Idea
Has this idea, or one like it, been proposed before?
Yes, #67316 is very similar. One of the main differences here is that this change would aligns more closely with how a switch typically works, and ends up being less verbose.
Does this affect error handling?
Yes. It attempts to make handling specific types and instances of errors less verbose, and make error handling more of a language level feature, rather than generally package level. The hope is if we make it easier, people will do it more.
Is this about generics?
No
Proposal
As I design enterprise apis, I frequently find myself needing to handle cases where an error.Is(err, target), or error.As(&err, target), or the error is simply not nil.
Language Spec Changes
I propose creating an error specific switch in Go.
ErrorSwitchStmt = "switch" [ SimpleStmt ";" ] ErrorSwitchGuard "{" { TypeCaseClause } "}" .
ErrorSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "\error" ")" .
ErrorCaseClause = ErrorSwitchCase ":" StatementList .
ErrorSwitchCase = "case" (ErrorType | error) | "default" .
Informal Change
While not a concrete example since I've made up the functions and errors involved, the following flow is one that I find myself creating often as I attempt to handle specific error cases:
I find the above code overly cumbersome, rather verbose, and unintuitive to a reader. I propose we solve this case, and many others like it by enhancing the switch statement with an error specific statement that has a behavior similar to a type switch, but some similarity with a typical value based switch as well. To ensure backwards compatibility, rather than use
switch v.(error)
in our guard clause, we would useswitch v.(\error)
. Notably, no cases in the switch statement will be evaluated UNLESSerr != nil
.The above example rewritten in this new syntax would look like so:
Now, not only is all of my error handling in one concise code block, I've also decreased the level of nesting, and the reader can clearly see the flow of my error handling logic. I know many will feel this is a small change for a lot of work. But I have seen repeatedly people simply omit error specific logic due to the verbosity and unwieldy nature of what we have today. I feel that making error handling more of a first class citizen in Go as a language will significantly enhance the developer experience, and result in a better experience for end users as a result.
Is this change backward compatible?
Yes
Orthogonality: How does this change interact or overlap with existing features?
No response
Would this change make Go easier or harder to learn, and why?
I actually feel it will make the language EASIER to learn, as those new to go will not have to learn about a separate errors package, but instead use a switch which they are probably already familiar with.
Cost Description
This change could maybe slightly increase the cost of compilation. Of course there is also the dev cost associated with implementing it.
Changes to Go ToolChain
No response
Performance Costs
No response
Prototype
No response
The text was updated successfully, but these errors were encountered: