Go error handling is really confusing me.

polaris · · 295 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I have a <code>*http.Request</code>, I call <code>.Cookie(&#34;session&#34;)</code> on it, get back a possible cookie and a possible error. I handle it by just <code>log.Fatal</code>ing it while I tool around, and I get <code>http: named cookie not present</code>.</p> <p>Makes sense, that is a perfectly expected error I want to handle. But what&#39;s the pattern for doing that? In Ruby, for example, it would throw an exception like <code>CookieNotFound</code> and I would <code>rescue CookieNotFound</code> and then explain what to do in that situation. Do I just need to call the <code>Error()</code> function on the error, get the string, match against the string in a case statement, and copy logic between branches? I&#39;d love some examples of well-handled errors.</p> <p>As a side question: why is making things nil-able and passing separate possible errors around chosen over union types?</p> <hr/>**评论:**<br/><br/>oscooter: <pre><p>The http lib news up an instance of each type of error it will return and returns those. You can see <a href="https://golang.org/src/net/http/request.go?s=12816:12870#L359">here</a> that the Cookie func will return the ErrNoCookie instance in the http package.</p> <p>So you can check if it&#39;s a the cookie not present error by doing</p> <pre><code>if err == http.ErrNoCookie { // handle this specific error } </code></pre> <p>The <a href="https://golang.org/pkg/net/http/#pkg-variables">documentation</a> for the http package also shows some of the other errors the package can return.</p> <p>Note that this can vary by package. The stdlib of go typically uses this method but other packages may expect you to do a type assertion on the error to check which type of error you got back.</p> <p><a href="https://blog.golang.org/error-handling-and-go">Here&#39;s</a> a handy article that explains the type assertion method in more depth.</p></pre>acln0: <pre><p>The return value of the <code>Error() string</code> method is purely informative and should never be used for flow control.</p> <p>Errors come in a number of flavors and good libraries document the errors they return.</p> <p>The first flavor is errors like <code>http.ErrNoCookie</code>, <code>io.EOF</code> or <code>bufio.ErrBufferFull</code>. Such errors are effectively constants and are usually named <code>ErrSomething</code>. You check for them with simple equality:</p> <pre><code>if err == http.ErrNoCookie { // do something } </code></pre> <p>Another flavor is like <code>net.OpError</code>, <code>os.PathError</code>, or <code>strconv.NumError</code>, which represent a type of error rather than an exact error. These usually wrap an inner error with additional information. Such error types are usually named <code>SomethingError</code>. You check for such errors using a type assertion, like so:</p> <pre><code>if perr, ok := err.(*os.PathError); ok { // use concrete information in perr } </code></pre> <p>Finally, you have interfaces like <code>net.Error</code>, which are desirable over concretely typed errors, because they reduce potential coupling between packages. Think of the <code>net.Error</code> interface as being a piece of documentation for optional methods the errors returned by package <code>net</code> may have.</p> <p>If a type which implements <code>error</code> also implements a <code>Timeout() bool</code> method, the caller need not know about the package the error came from or its concrete type. A check like this is sufficient:</p> <pre><code>type timeouter interface { error Timeout() bool } if terr, ok := err.(timeouter); ok { // check terr.Timeout() } </code></pre></pre>mxxxz: <pre><p>is this handling equivalent of try-catch statements in Java?</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

295 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传