Go 中的惯用过滤错误
Idiomatically filtering errors in Go
Go 中的 error
类型非常广泛,实际包含的类型可能因平台和版本而异。通过错误的字符串值 error.Error()
?
来过滤我们期望的错误是否惯用
例如:
_, err := conn.Write(b)
if err != nil {
if !strings.Contains(err.Error(), "peer reset") {
log.Print(err)
}
return
}
有更好的方法吗?
我不确定我在说什么你不知道,但我已经看到了一些处理它的方法:与导出并出现在 godoc 中的已知实例进行比较,比如 io.EOF
或 os.ErrNotExist
;当文档承诺某种类型的错误时使用类型断言或开关,例如 *os.PathError
或 *os.LinkError
;或放弃并查看消息。第一个应该足够清楚,你已经在你的问题中完成了第三个;检查类型可能如下所示:
if pathErr, ok := err.(*os.PathError); ok {
log.Fatal("Bad path " + pathErr.Path + ", giving up")
} else if err != nil {
return err
}
我认为这种情况很少见,但如果您涉及多个潜在类型,您可以想象使用 type switch:
switch err.(type) {
case *os.PathError, *os.LinkError:
log.Fatal("oof")
case nil:
// nothing; prevents default
default:
log.Fatal("huh")
}
(这里错误和行为的选择有点傻——我只是想用语法建立一个模板。)
您在问题中提到的困难部分:可能不清楚您对将返回哪些错误有什么保证。我知道,例如,净错误的 1.5 release notes say that they're standardizing more on net.OpError 比以前多了,但这就是我所知道的。如果有您认为不清楚的重要案例,可能需要深入研究您正在调用的包的源代码,或者向人们提问。
errors.Is
和 errors.As
添加到较新版本的 Go 现在可以解决这个问题。
Go 中的 error
类型非常广泛,实际包含的类型可能因平台和版本而异。通过错误的字符串值 error.Error()
?
例如:
_, err := conn.Write(b)
if err != nil {
if !strings.Contains(err.Error(), "peer reset") {
log.Print(err)
}
return
}
有更好的方法吗?
我不确定我在说什么你不知道,但我已经看到了一些处理它的方法:与导出并出现在 godoc 中的已知实例进行比较,比如 io.EOF
或 os.ErrNotExist
;当文档承诺某种类型的错误时使用类型断言或开关,例如 *os.PathError
或 *os.LinkError
;或放弃并查看消息。第一个应该足够清楚,你已经在你的问题中完成了第三个;检查类型可能如下所示:
if pathErr, ok := err.(*os.PathError); ok {
log.Fatal("Bad path " + pathErr.Path + ", giving up")
} else if err != nil {
return err
}
我认为这种情况很少见,但如果您涉及多个潜在类型,您可以想象使用 type switch:
switch err.(type) {
case *os.PathError, *os.LinkError:
log.Fatal("oof")
case nil:
// nothing; prevents default
default:
log.Fatal("huh")
}
(这里错误和行为的选择有点傻——我只是想用语法建立一个模板。)
您在问题中提到的困难部分:可能不清楚您对将返回哪些错误有什么保证。我知道,例如,净错误的 1.5 release notes say that they're standardizing more on net.OpError 比以前多了,但这就是我所知道的。如果有您认为不清楚的重要案例,可能需要深入研究您正在调用的包的源代码,或者向人们提问。
errors.Is
和 errors.As
添加到较新版本的 Go 现在可以解决这个问题。