Golang中如何检查`client.Do()`的错误?
Golang中如何检查client.Do()的错误?
在我的Go程序中,我按如下方式发起请求:
// 准备请求
req, err := http.NewRequest("GET", path, nil)
if err != nil {
log.Fatalln("Error preparing request.", err)
}
client := &http.Client{Timeout: time.Second * 12}
// 执行请求
request, err := client.Do(req)
if err != nil {
log.Fatalln("Failed to make request.", err)
}
defer request.Body.Close()
我遇到的其中一个错误是:
Get https://www.maps.google.com: dial tcp: lookup www.maps.google.com: no such host
我在调整代码以检查“no such host”错误时遇到了困难。该如何实现呢?
通过查阅client.Do()文档,我了解到返回的错误类型为*url.Error。我在这里找到了该错误的定义,并注意到Error()函数返回一个字符串。或许我可以检查这个字符串来识别“no such host”错误?
我尝试过的方法包括:
if string(err) == url.InvalidHostError() {
log.Println("Host not found.")
}
if err(*url.Error) == url.InvalidHostError() {
log.Println("Host not found.")
}
if strings.Contains(err.(*Error), "no such host") {
log.Println("Host not found.")
}
我已经通过谷歌搜索、阅读错误处理相关文章、研究url.go的代码,并查阅了我手头的《Go编程语言》一书。但我仍感觉对这个主题理解不够深入,陷入了困境。
欢迎任何建议!
更多关于Golang中如何检查`client.Do()`的错误?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
这个类型
type Error struct {
Op string
URL string
Err error
}
包含三个成员 Op、URL 和 Err,你可以这样访问:
fmt.Println(err.Err)
更多关于Golang中如何检查`client.Do()`的错误?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Juk:
获取 https://www.maps.google.com:拨号 tcp:查找 http://www.maps.google.com:无此主机
你不需要过多检查错误。在浏览器中验证后发现所声称的地址并不存在。
**www.maps.google.com** 的服务器 IP 地址无法找到。
可能你想说的是 maps.google.com。
但也许他们想检查错误信息,以便提供更友好的用户提示?
我处理的许多——如果不是全部——客户在遇到类似错误时,会立即联系内部IT部门,就因为错误信息里出现了tcp这个词。这可是网络相关的问题……他们甚至不会继续阅读到关键部分。
在这种情况下,我的做法是使用err.Error()获取字符串表示形式,然后对字符串化的错误信息进行正则表达式匹配,同时祈祷错误信息的结构永远不会改变。
err.Error()
感谢大家的积极参与,非常感激。😊
lutzhorn: 你可以访问:
fmt.Println(err.Err)
这让我得到了错误信息:
err.Err undefined (type error has no field or method Err)
这让我感到困惑,因为我明白你的意思。
NobbZ: 在这种情况下,我通常使用
err.Error()来获取字符串表示形式,然后对字符串化的错误应用一些正则表达式,祈祷错误消息的结构永远不会改变。
谢谢你的想法,这是个不错的方法。我已经调整了我的代码,现在这样做:
request, err := client.Do(req)
if err != nil {
if strings.Contains(err.Error(), "no such host") {
log.Printf("Host not found: %s", path)
} else {
log.Println("Failed to make request.", err)
}
return ""
}
defer request.Body.Close()
这样运行得很好!😊(虽然需要更精确一些,并且可能需要第二次尝试,但这是以后的事情。)
geosoft1: 你不需要太多的错误检查。在浏览器中检查,声称的地址不存在。
确实如此,说得好。但我的应用程序希望检查100万个域名,不想逐个检查每个域名的网站地址是什么。
要检查client.Do()返回的错误是否为"no such host"错误,你需要使用类型断言来访问底层的*url.Error,然后检查其Err字段。以下是一个完整的示例:
req, err := http.NewRequest("GET", path, nil)
if err != nil {
log.Fatalln("Error preparing request.", err)
}
client := &http.Client{Timeout: time.Second * 12}
request, err := client.Do(req)
if err != nil {
// 检查是否为URL错误
if urlErr, ok := err.(*url.Error); ok {
// 检查底层错误是否为DNS查找错误
if netErr, ok := urlErr.Err.(*net.OpError); ok {
if dnsErr, ok := netErr.Err.(*net.DNSError); ok && dnsErr.IsNotFound {
log.Println("Host not found:", dnsErr.Name)
// 处理主机不存在的情况
return
}
}
}
log.Fatalln("Failed to make request.", err)
}
defer request.Body.Close()
或者,你也可以使用更简洁的错误链检查方式:
req, err := http.NewRequest("GET", path, nil)
if err != nil {
log.Fatalln("Error preparing request.", err)
}
client := &http.Client{Timeout: time.Second * 12}
request, err := client.Do(req)
if err != nil {
var dnsErr *net.DNSError
if errors.As(err, &dnsErr) && dnsErr.IsNotFound {
log.Println("Host not found:", dnsErr.Name)
// 处理主机不存在的情况
return
}
log.Fatalln("Failed to make request.", err)
}
defer request.Body.Close()
在第二个示例中,errors.As函数会遍历错误链,查找匹配的*net.DNSError类型,如果找到并且IsNotFound为true,则表示是"no such host"错误。
对于你提到的字符串检查方法,虽然技术上可行,但不推荐,因为错误消息可能因不同系统或Go版本而变化。使用类型系统进行检查更加可靠。

