这篇是对 errors 包 的姿势挖掘
从 http.Get()返回的错误 判断 syscall.ECONNREFUSED 错误.以前要对 go 标准库 error 结构有点熟悉,才能写出下面的代码
func CmdErr(err error) {
if err == nil {
return
}
if uerr, ok := err.(*url.Error); ok {
if noerr, ok := uerr.Err.(*net.OpError); ok {
if scerr, ok := noerr.Err.(*os.SyscallError); ok {
if scerr.Err == syscall.ECONNREFUSED {
fmt.Printf("gurl: (7) couldn't connect to host\n")
return
}
}
}
}
fmt.Printf("%s\n", err)
}
现在只要知道,syscall.ECONNREFUSED 就行。先用 Unwrap 不停的解包 error。最后可能得到需要的 err
func newCmdErr(err error) {
for {
err = errors.Unwrap(err)
if err == nil {
break
}
if err == syscall.ECONNREFUSED {
fmt.Printf("gurl: (7) couldn't connect to host\n")
return
}
}
}
一起挖掘 errors 包的用法
// 这是代码量最少的写法。
func newCmdErr2(err error) {
if errors.Is(err, syscall.ECONNREFUSED) {
fmt.Printf("gurl: (7) couldn't connect to host\n")
return
}
}
1
rootxigua 2019-10-14 10:11:16 +08:00
那如果 err 不为空,并且不等于 syscall.ECONNREFUSED,这个循环会结束吗?
|
2
edussx 2019-10-14 10:28:33 +08:00
@rootxigua 这种情况下 errors.Unwrap(err)这行会一直跑,直到返回 nil,然后在下面 break 跳出循环
具体参考这个方法的实现: https://golang.org/src/errors/wrap.go?s=372:400#L4 |
3
lizhenda 2019-10-14 10:45:35 +08:00
看起来写法不错,更易读了
|
6
iugo 2019-10-14 11:43:19 +08:00
还是觉得 Go 的错误处理是个值得商榷的点.
|
7
Hanggi 2019-10-14 12:07:38 +08:00
这个代码本来就不用写什么气功波吧?有谁会这么写吗?
|
8
guonaihong OP @reus 是的,这是最优解。
|
9
boyhailong 2019-10-14 12:26:48 +08:00
气功波? 返回值不想处理可以忽略的
|
10
guonaihong OP @boyhailong 这里的用法是,如果是 syscall.ECONNREFUSED 的错误打印 提示信息。所以就不能忽略。。。
|
11
guonaihong OP @iugo 是的,现在比较大的痛点有
``` go fd, err := os.Open("文件") if err != nil { return err } ``` 如果 go 里面有语法糖,在语句结尾加个符号,生成 if err != nil { return err}的代码就好了。比如下面的伪代码. fd, err := os.Open("文件“) ? |
12
ChristopherWu 2019-10-14 17:12:52 +08:00
实不相瞒,我看不懂这代码在搞啥子
``` func CmdErr(err error) { if err == nil { return } if uerr, ok := err.(*url.Error); ok { if noerr, ok := uerr.Err.(*net.OpError); ok { if scerr, ok := noerr.Err.(*os.SyscallError); ok { if scerr.Err == syscall.ECONNREFUSED { fmt.Printf("gurl: (7) couldn't connect to host\n") return } } } } fmt.Printf("%s\n", err) } ``` |
13
guonaihong OP @ChristopherWu 查询 err 看是否包含 syscall.ECONNREFUSED 这种情况。go1.13 以前只能这么干。。
|
14
Nitroethane 2019-10-14 18:30:31 +08:00 via Android
@guonaihong 这不就是 rust 中的语法么...
|
15
guonaihong OP @Nitroethane 对的,伪代码符号参考的 rust ?号,go 现在没有,有就好了。
|
16
EscYezi 2019-10-14 21:06:36 +08:00 via iPhone
不停的 unwrap 怎么看起来像在手动完成 java 的 printStackTrace......
|
17
guonaihong OP @EscYezi 没玩过 java。。。
|
18
mason961125 2019-10-14 21:25:01 +08:00
这样写,我觉得 https://github.com/hashicorp/errwrap 更好
|
19
guonaihong OP @mason961125 谢了,我明天玩下。
|
20
zjh6 2019-10-15 08:15:25 +08:00
气功波,是搞笑.
|