Ich möchte identifizieren, welche Art von Fehler in der Netzwerkebene aufgetreten ist. Der einzige Weg, den ich gefunden habe, war die Fehlermeldungen mit einem regulären Ausdruck zu überprüfen, aber jetzt habe ich entdeckt, dass diese Nachrichten in verschiedenen Sprachen (abhängig von der Betriebssystemkonfiguration) sein können, was es schwierig macht, sie mit regulären Ausdrücken zu erkennen. Gibt es einen besseren Weg, es zu tun?Portable Möglichkeit, verschiedene Arten von Netzwerkfehlern in Golang zu erkennen
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")
}
}
Ergebnis:
$ go run neterrors.go
Timeout
Unknown host
Connection refused
entdecken ich das Problem, wenn das System in einem Windows-Betriebssystem mit Portugiesisch als Standardsprache zu testen.
[EDIT]
fand ich einen Weg, es zu tun, um die OpError verwenden. Hier ist die checkErr-Funktion wieder mit dem neuen Ansatz. Wenn jemand eine bessere Lösung hat, werde ich sehr froh sein, es zu kennen!
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")
}
}
}
[EDIT 2]
nach seong Antwort aktualisiert.
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 gibt '* os.SyscallError' anstelle von' syscall.Errno' zurück –