我想確定網絡級別發生了哪種錯誤。我發現的唯一方法是使用正則表達式檢查錯誤消息,但是現在我發現這些消息可以使用不同的語言(取決於操作系統配置),從而難以通過正則表達式進行檢測。有沒有更好的方法來做到這一點?便攜式檢測Golang中的各種網絡錯誤
package main
import (
"github.com/miekg/dns"
"net"
"regexp"
)
func main() {
var c dns.Client
m := new(dns.Msg)
m.SetQuestion("3com.br.", dns.TypeSOA)
_, _, err := c.Exchange(m, "ns1.3com.com.:53")
checkErr(err)
m.SetQuestion("example.com.", dns.TypeSOA)
_, _, err = c.Exchange(m, "idontexist.br.:53")
checkErr(err)
m.SetQuestion("acasadocartaocuritiba.blog.br.", dns.TypeSOA)
_, _, err = c.Exchange(m, "ns7.storedns22.in.:53")
checkErr(err)
}
func checkErr(err error) {
if err == nil {
println("Ok")
} else if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
println("Timeout")
} else if match, _ := regexp.MatchString(".*lookup.*", err.Error()); match {
println("Unknown host")
} else if match, _ := regexp.MatchString(".*connection refused.*", err.Error()); match {
println("Connection refused")
} else {
println("Other error")
}
}
結果:
$ go run neterrors.go
Timeout
Unknown host
Connection refused
我爲默認語言的Windows操作系統與葡萄牙的測試系統時發現的問題。
[編輯]
我找到了一種方法使用OpError做到這一點。新方法再次使用checkErr函數。如果有人有更好的解決方案,我會很高興知道它!
func checkErr(err error) {
if err == nil {
println("Ok")
} else if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
println("Timeout")
} else if opError, ok := err.(*net.OpError); ok {
if opError.Op == "dial" {
println("Unknown host")
} else if opError.Op == "read" {
println("Connection refused")
}
}
}
[EDIT2]
洪城答案後更新。
func checkErr(err error) {
if err == nil {
println("Ok")
return
} else if netError, ok := err.(net.Error); ok && netError.Timeout() {
println("Timeout")
return
}
switch t := err.(type) {
case *net.OpError:
if t.Op == "dial" {
println("Unknown host")
} else if t.Op == "read" {
println("Connection refused")
}
case syscall.Errno:
if t == syscall.ECONNREFUSED {
println("Connection refused")
}
}
}
go1.6返回'* os.SyscallError'而不是'syscall.Errno' –