Files
silo-server/internal/historyimport/errors.go

84 lines
1.9 KiB
Go

package historyimport
import (
"context"
"crypto/x509"
"errors"
"net"
"net/url"
"strings"
)
// IsReachabilityError reports whether err indicates the upstream server could
// not be reached due to URL, DNS, connection, timeout, or TLS issues.
func IsReachabilityError(err error) bool {
if err == nil || UpstreamHTTPStatus(err) > 0 {
return false
}
if errors.Is(err, context.DeadlineExceeded) {
return true
}
var urlErr *url.Error
if errors.As(err, &urlErr) {
if urlErr.Timeout() || urlErr.Op == "parse" {
return true
}
}
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
return true
}
var dnsErr *net.DNSError
if errors.As(err, &dnsErr) {
return true
}
var opErr *net.OpError
if errors.As(err, &opErr) {
return true
}
var addrErr *net.AddrError
if errors.As(err, &addrErr) {
return true
}
var invalidCertErr x509.CertificateInvalidError
if errors.As(err, &invalidCertErr) {
return true
}
var hostnameErr x509.HostnameError
if errors.As(err, &hostnameErr) {
return true
}
var unknownAuthorityErr x509.UnknownAuthorityError
if errors.As(err, &unknownAuthorityErr) {
return true
}
var systemRootsErr x509.SystemRootsError
if errors.As(err, &systemRootsErr) {
return true
}
message := strings.ToLower(err.Error())
return strings.Contains(message, "connection refused") ||
strings.Contains(message, "no such host") ||
strings.Contains(message, "dial tcp") ||
strings.Contains(message, "lookup ") ||
strings.Contains(message, "server misbehaving") ||
strings.Contains(message, "missing protocol scheme") ||
strings.Contains(message, "unsupported protocol scheme") ||
strings.Contains(message, "certificate") ||
strings.Contains(message, "tls:") ||
strings.Contains(message, "x509:") ||
strings.Contains(message, "timeout") ||
strings.Contains(message, "no reachable server url")
}