gpt4 book ai didi

error-handling - Go 错误处理、类型断言和 net 包

转载 作者:IT老高 更新时间:2023-10-28 13:06:27 26 4
gpt4 key购买 nike

我正在学习并试图了解如何从通用错误类型中获取更详细的错误信息。我将使用的示例来自 net 包,特别是 DialTimeout function .

签名是

func DialTimeout(network, address string, timeout time.Duration) (Conn, error)

error type 只定义了一个 Error() string 函数。如果我想查明 DialTimeout 失败的确切原因,我该如何获取该信息?我发现我可以使用类型断言来获取 net.Error 特定的错误:

con, err := net.DialTimeout("tcp", net.JoinHostPort(address, "22"),
time.Duration(5) * time.Second)
if err != nil {
netErr, ok := err.(net.Error)
if ok && netErr.Timeout() {
// ...
}
}

但这只会告诉我我是否有超时。例如,假设我想区分拒绝连接和没有主机路由。我怎样才能做到这一点?

也许 DialTimeout 太高级了,无法给我提供那种细节,但即使查看 syscall.Connect ,我看不到如何得到具体的错误。它只是说它返回通用错误类型。将其与 Posix connect 进行比较,这将让我知道为什么它因各种返回码而失败。

我的一般问题是:如果 golang 文档没有告诉我可能返回什么类型的错误,我应该如何从通用 error 类型中提取错误详细信息?

最佳答案

大多数网络操作返回 *OpError其中包含有关错误的详细信息并实现 net.Error 接口(interface)。所以对于大多数用例来说,使用 net.Error 就足够了就像你已经做过的那样。

但对于您的情况,您希望将返回的错误断言为 *net.OpError 和使用内部错误:

if err != nil {
if oerr, ok := err.(*OpError); ok {
// Do something with oerr.Err
}
}

一旦你这样做了,你就处于平台依赖的领域,就像 Linux 下的系统调用一样可能与 Windows 下的失败不同。对于 Linux,您可以这样做:

if oerr.Err == syscall.ECONNREFUSED {
// Connection was refused :(
}

syscall 包包含适用于您平台的重要错误常量。很遗憾golang 网站只显示系统调用包 for Linux amd64 .见 here对于 ECONNREFUSED

找出类型

下一次你想知道某个函数实际返回了什么而你无法做出它的头和尾,尝试使用 fmt.Printf 中指定的 %#v 格式(和 friend ):

 fmt.Printf("%#v\n", err)
// &net.OpError{Op:"dial", Net:"tcp", Addr:(*net.TCPAddr)(0xc20006d390), Err:0x6f}

它将打印详细的类型信息,通常很有帮助。

关于error-handling - Go 错误处理、类型断言和 net 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20926947/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com