<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Error-Handling on Roberto Selbach</title><link>https://rselbach.com/tags/error-handling/</link><description>Recent content in Error-Handling on Roberto Selbach</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Wed, 17 Jul 2019 01:26:08 +0000</lastBuildDate><atom:link href="https://rselbach.com/tags/error-handling/index.xml" rel="self" type="application/rss+xml"/><item><title>Try was worth trying</title><link>https://rselbach.com/try-was-worth-trying/</link><pubDate>Wed, 17 Jul 2019 01:26:08 +0000</pubDate><guid>https://rselbach.com/try-was-worth-trying/</guid><description>&lt;p&gt;The Go proposal committee has &lt;a href="https://github.com/golang/go/issues/32437#issuecomment-512035919"&gt;declined the &lt;code&gt;try&lt;/code&gt; proposal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am disappointed. I also think this is open source working exactly as it should.&lt;/p&gt;
&lt;p&gt;The proposal was not dropped because one person with commit access disliked it. A concrete design was published, tools were written to try it on existing code, hundreds of examples and objections were discussed, and the people behind it kept answering questions long after I would have quietly disconnected my router and moved to the woods.&lt;/p&gt;
&lt;p&gt;Most importantly, the Proposal Review Committee made its decision in response to that discussion. The closing note mentions problems the original design had missed, including debugging prints and code coverage. It also admits something more fundamental: many Go programmers do not agree that the verbosity of error forwarding is a problem worth changing the language to solve.&lt;/p&gt;
&lt;p&gt;That is a good reason to stop. A language belongs to the people who have to read it, and a change to control flow needs more than a clever specification. The community worked through the tradeoffs together and the committee made the call. I may disagree with the result, but I trust the process far more after seeing it work.&lt;/p&gt;
&lt;p&gt;Still, I think this will eventually look like a missed opportunity.&lt;/p&gt;
&lt;p&gt;The argument against &lt;code&gt;try&lt;/code&gt; was strongest when it was used inside nested expressions:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;encode&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;read&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I do not want to debug that either. But bad nesting was not the only possible future. The ordinary form was much less alarming:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ioutil&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ReadFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Unmarshal&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;cfg&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One operation per line, errors still in the function signature, no exceptions, and an explicit &lt;code&gt;if&lt;/code&gt; whenever local handling mattered. I think that style would have become normal very quickly. It looks unusual today mostly because it is new.&lt;/p&gt;
&lt;p&gt;There is a difficult bias in evaluating syntax: familiar boilerplate does not feel like syntax anymore. We see &lt;code&gt;if err != nil&lt;/code&gt; and read “return the error.” We see &lt;code&gt;try&lt;/code&gt; and inspect every unusual corner because it is new. That scrutiny is necessary before changing a language, but it is not a neutral comparison.&lt;/p&gt;
&lt;p&gt;Rust went through a remarkably similar argument around &lt;code&gt;try!&lt;/code&gt; and later &lt;code&gt;?&lt;/code&gt;. People worried about hidden control flow and two ways to write the same thing. Once programmers had lived with it, many came to consider it one of the language&amp;rsquo;s better features. Go is not Rust and should not become Rust, but people do learn new control-flow notation. We already did it with &lt;code&gt;defer&lt;/code&gt; and &lt;code&gt;go&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There is another group absent from a discussion among current Go programmers: people who did not choose Go because they found its error handling tedious. It is almost impossible to measure them from inside the community. The people most comfortable with the status quo are, unsurprisingly, the people who stayed.&lt;/p&gt;
&lt;p&gt;None of that means the committee should have ignored the reaction and forced &lt;code&gt;try&lt;/code&gt; through. That would have damaged the language and the community more than a little error boilerplate ever could. Declining it was the right decision &lt;em&gt;now&lt;/em&gt;, given the lack of agreement about both the problem and the solution.&lt;/p&gt;
&lt;p&gt;But I suspect we solved the social problem by leaving the technical one untouched. Years from now we may add something remarkably similar under another name, after enough other languages have made the idea feel ordinary. Or we may simply keep writing the same four lines and insist they are valuable because we have become very fast at not seeing them.&lt;/p&gt;
&lt;p&gt;Either way, &lt;code&gt;try&lt;/code&gt; was worth trying. The proposal improved our understanding of the problem, and its rejection proved that the Go community can say no even after a great deal of work has been invested.&lt;/p&gt;
&lt;p&gt;That is not failure. I just hope it is not the last word on improving error handling.&lt;/p&gt;</description></item><item><title>The argument over try</title><link>https://rselbach.com/the-argument-over-try/</link><pubDate>Mon, 10 Jun 2019 23:18:42 +0000</pubDate><guid>https://rselbach.com/the-argument-over-try/</guid><description>&lt;p&gt;It has been six days since &lt;a href="https://github.com/golang/go/issues/32437"&gt;the &lt;code&gt;try&lt;/code&gt; proposal&lt;/a&gt; was posted and the issue already has hundreds of comments.&lt;/p&gt;
&lt;p&gt;Robert Griesemer has posted &lt;a href="https://github.com/golang/go/issues/32437#issuecomment-500613160"&gt;a useful summary of the discussion&lt;/a&gt;. After reading far too much of the thread, I think the arguments are clearer now. They are also better than “I hate typing &lt;code&gt;if err != nil&lt;/code&gt;” versus “real programmers enjoy typing it,” which is where these discussions usually go to die.&lt;/p&gt;
&lt;p&gt;The strongest case for &lt;code&gt;try&lt;/code&gt; is ordinary sequential code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;readConfig&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) (&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Config&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ioutil&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ReadFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cfg&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Config&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Unmarshal&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;cfg&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;cfg&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There is very little error handling in the expanded version. Both errors are simply returned. The extra &lt;code&gt;if&lt;/code&gt; statements interrupt the description of what the function does without adding a decision.&lt;/p&gt;
&lt;p&gt;This is not merely speculation. Some people have tried converting code from the standard library. One conclusion was that &lt;code&gt;try&lt;/code&gt; made most of those examples easier to read. Another person looked at much the same evidence and reached almost exactly the opposite conclusion.&lt;/p&gt;
&lt;p&gt;The proposal has other good properties. It does not introduce exceptions. Errors remain ordinary return values. Existing code keeps working. &lt;code&gt;try&lt;/code&gt; handles the dull case while an &lt;code&gt;if&lt;/code&gt; remains available whenever the error needs local attention. I find that separation appealing.&lt;/p&gt;
&lt;h2 id="the-invisible-return"&gt;The invisible return&lt;/h2&gt;
&lt;p&gt;The best argument against it is simple: &lt;code&gt;try&lt;/code&gt; looks like a function call but changes the control flow of its caller.&lt;/p&gt;
&lt;p&gt;Consider this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;tp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ReadMIMEHeader&lt;/span&gt;()))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That assignment can return from the enclosing function. A struct literal containing &lt;code&gt;try&lt;/code&gt; can return. A nested expression can contain several possible returns on the same source line. Today my eyes know that constructing a value does not quietly leave the function. With &lt;code&gt;try&lt;/code&gt;, they would have to search inside every expression.&lt;/p&gt;
&lt;p&gt;Some commenters therefore prefer a keyword or statement form:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;try&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Open&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is harder to miss, but it is also a larger language change and it gives up the proposal&amp;rsquo;s useful ability to fit where an expression fits. Restricting &lt;code&gt;try&lt;/code&gt; may make it safer while removing much of what makes it attractive. Language design is fun like that.&lt;/p&gt;
&lt;p&gt;There are practical problems too. If I add a debugging print to one particular failure today, there is an obvious block in which to put it. If several operations use &lt;code&gt;try&lt;/code&gt; and one deferred handler wraps all of their errors, identifying the exact operation may require changing the code back to an &lt;code&gt;if&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Coverage has a similar problem. The explicit error block is visible to coverage tools. A hidden return inside &lt;code&gt;try&lt;/code&gt; creates a branch that source-level coverage needs to represent somehow. Debuggers and stack traces also need enough information to distinguish multiple &lt;code&gt;try&lt;/code&gt; calls on one line. These are practical objections, not just a matter of taste.&lt;/p&gt;
&lt;h2 id="the-context-problem"&gt;The context problem&lt;/h2&gt;
&lt;p&gt;I am less convinced by the proposed use of &lt;code&gt;defer&lt;/code&gt; for error context than I am by &lt;code&gt;try&lt;/code&gt; itself.&lt;/p&gt;
&lt;p&gt;A deferred handler can add function-level context once:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;HandleErrorf&lt;/span&gt;(&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;reading configuration %s&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is lovely when every failure in the function deserves the same context. It is less useful when opening the file, parsing it, and validating it each need different information. The handler also runs on every return and encourages named error results. None of this is fatal, but it means the proposal is strongest exactly where error forwarding is least interesting.&lt;/p&gt;
&lt;p&gt;So I still like &lt;code&gt;try&lt;/code&gt;, with qualifications large enough to require their own parking space. I would avoid nesting it and use one operation per line. I would keep &lt;code&gt;if err != nil&lt;/code&gt; wherever an error needs local context, cleanup, logging, or translation. In that style the hidden control flow is bounded and the useful code becomes much easier to see.&lt;/p&gt;
&lt;p&gt;But Go cannot add a feature on the assumption that everybody will use my preferred style. If nested &lt;code&gt;try&lt;/code&gt; is legal, nested &lt;code&gt;try&lt;/code&gt; will exist. If a return can hide in a composite literal, people will write code that does exactly that.&lt;/p&gt;
&lt;p&gt;I thought the original proposal was likely to fail because it &lt;em&gt;felt&lt;/em&gt; unlike Go. The discussion has produced better reasons than feelings. I still think we may be rejecting an idea that would become ordinary and useful with time, but it is no longer difficult to understand why so many people are wary of it.&lt;/p&gt;</description></item><item><title>I think I like try</title><link>https://rselbach.com/i-think-i-like-try/</link><pubDate>Wed, 05 Jun 2019 18:42:17 +0000</pubDate><guid>https://rselbach.com/i-think-i-like-try/</guid><description>&lt;p&gt;Yesterday Robert Griesemer posted &lt;a href="https://github.com/golang/go/issues/32437"&gt;a proposal for a new &lt;code&gt;try&lt;/code&gt; built-in&lt;/a&gt; in Go. I have read the design document twice now and I think I like it.&lt;/p&gt;
&lt;p&gt;I am not entirely comfortable saying that.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://rselbach.com/returns-in-go-and-c/"&gt;Two years ago I wrote&lt;/a&gt; that explicit error handling was exactly one of the things I loved about Go. I still do. The interesting question here is whether returning an error unchanged really counts as handling it.&lt;/p&gt;
&lt;p&gt;The proposal turns this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;f&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Open&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;filename&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;into this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;f&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Open&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;filename&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If &lt;code&gt;os.Open&lt;/code&gt; returns an error, &lt;code&gt;try&lt;/code&gt; places it in the enclosing function&amp;rsquo;s error result and returns from that function. Otherwise it gives us the other result. Errors remain values, functions still say that they return errors, and there are no exceptions jumping across some unknowable number of stack frames.&lt;/p&gt;
&lt;p&gt;That is the part I like. A surprising amount of Go code is not really &lt;em&gt;handling&lt;/em&gt; an error at all. It is checking the error and immediately passing it to the caller. I love explicit error handling, but writing four lines does not make that decision four times more explicit.&lt;/p&gt;
&lt;p&gt;And yet &lt;code&gt;try&lt;/code&gt; feels wrong.&lt;/p&gt;
&lt;p&gt;It looks like a function but it can return from the function that called it. That is not something ordinary Go functions can do. The control flow is hidden inside an expression, and Go has spent the last ten years making control flow painfully, wonderfully obvious. There is no &lt;code&gt;return&lt;/code&gt; on the line. It just returns.&lt;/p&gt;
&lt;p&gt;The proposed way to add context also takes some getting used to. Instead of wrapping each error where it happens, a function can use a deferred handler to decorate the returned error. Using the helper sketched in the design, it would look something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;readConfig&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) (&lt;span style="color:#a6e22e"&gt;cfg&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Config&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;HandleErrorf&lt;/span&gt;(&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;read configuration %s&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ioutil&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ReadFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;try&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Unmarshal&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;cfg&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cfg&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I am not sure I love the named result or the indirection in the handler. But I do like being able to see the actual operation without each line being separated from the next by the same little error-return ceremony.&lt;/p&gt;
&lt;p&gt;My guess is that this proposal will not pass. It is a small addition in terms of specification and implementation, but a radical change in how Go code reads. Those are often the hardest changes: technically tiny and culturally enormous.&lt;/p&gt;
&lt;p&gt;I also suspect that, if it does not pass, we may look back several years from now and wonder why it seemed so frightening. New syntax always has the disadvantage of looking unfamiliar in every example. The existing syntax has had a decade to become invisible.&lt;/p&gt;
&lt;p&gt;Maybe I am wrong and &lt;code&gt;try&lt;/code&gt; will turn real programs into a collection of secret exits. But the idea behind it is sound: keep explicit errors, while admitting that forwarding an error is not the interesting part of error handling.&lt;/p&gt;
&lt;p&gt;That seems worth trying.&lt;/p&gt;</description></item></channel></rss>