如果一段代码有自己的错误类型,如
var ErrSomethingWentWrong = errors.New("Something went wrong"
我相信我的代码我可以做到这一点
import github.com/therepo/theproject/thepackage/thatexportstheaboveerror
// code that might return the above error
if err == thatexportstheaboveerror.ErrSomethingWentWrong {
// handle the particular case
}
如果像本例中那样通过fmt.Errorf
返回错误,会发生什么情况?
return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", keys(tried))
值(或类型或其他)检查/Assert应该如何执行?这是唯一的办法吗?
if err != nil {
if strings.Contains(err.Error(), "unable to authenticate") {
// handle the particular error
}
}
2条答案
按热度按时间thtygnil1#
从Go语言1.13版本开始,the
errors
package包含了“ Package ”错误的概念。返回“wrapped”错误的例程使用格式中的%w
动词调用fmt.Errorf
,将内部错误 Package 到外部错误中。然后可以测试外部错误以查看其是否包含特定的内部错误。在此之前,
xerrors
提供了相同的一般概念。这两种方法都要求产生错误值的人使用提供的 Package 接口。您所询问的例程(https://godoc.org/golang.org/x/crypto/ssh的一部分)并没有做到这一点。一些没有 Package 错误的旧代码提供了某种类型的错误测试函数。例如,当
os.Open
返回一个错误时,os.IsNotExist
会告诉您该错误是否是因为文件不存在。不幸的是,这个特定的包没有这样的测试,所以如果你真的想以编程方式知道这个错误来自这个特定的源,你几乎只能坚持你所建议的(直接字符串检查)。
1zmg4dgp2#
虽然
golang.org/x/crypto/ssh
包不会出现sentinel错误(wrapped或其他),但ssh.Dial
函数提供了使用ssh.NewClientConn
进行更多控制的建议。我做了一些简单的研究,看起来这可能是解决方案:net.Dial
获得net.Conn
ssh.NewClientConn
获取ssh.Conn
和控制通道ssh.NewClient
获得ssh.Client
这允许您将便利功能分解为三个独立的步骤,以便您可以更好地识别这三个点中的哪一个是故障的来源,并显示自定义 Package 的错误,以便您的业务逻辑可以处理这些特定的场景(例如,“失败的端口连接尝试”与“失败的身份验证”)。