@@ -2,10 +2,7 @@ package uplog
2
2
3
3
import (
4
4
"context"
5
- "crypto/tls"
6
- "errors"
7
5
"net"
8
- "net/http"
9
6
"net/url"
10
7
"os"
11
8
"strings"
@@ -75,30 +72,47 @@ func getOsVersion() (string, error) {
75
72
}
76
73
77
74
func detectErrorType (err error ) ErrorType {
78
- var (
79
- dnsError * net.DNSError
80
- urlError * url.Error
81
- tlsVerifyCertError * tls.CertificateVerificationError
82
- syscallError syscall.Errno
83
- )
84
- if os .IsTimeout (err ) || errors .Is (err , syscall .ETIMEDOUT ) {
75
+ tryToUnwrapUnderlyingError := func (err error ) (error , bool ) {
76
+ switch err := err .(type ) {
77
+ case * os.PathError :
78
+ return err .Err , true
79
+ case * os.LinkError :
80
+ return err .Err , true
81
+ case * os.SyscallError :
82
+ return err .Err , true
83
+ case * url.Error :
84
+ return err .Err , true
85
+ case * net.OpError :
86
+ return err .Err , true
87
+ }
88
+ return err , false
89
+ }
90
+ unwrapUnderlyingError := func (err error ) error {
91
+ ok := true
92
+ for ok {
93
+ err , ok = tryToUnwrapUnderlyingError (err )
94
+ }
95
+ return err
96
+ }
97
+
98
+ unwrapedErr := unwrapUnderlyingError (err )
99
+ if os .IsTimeout (unwrapedErr ) {
85
100
return ErrorTypeTimeout
86
- } else if errors . As ( err , & dnsError ) && dnsError . IsNotFound {
101
+ } else if dnsError , ok := unwrapedErr .( * net. DNSError ); ok && isDnsNotFoundError ( dnsError ) {
87
102
return ErrorTypeUnknownHost
88
- } else if os .IsNotExist (err ) || os .IsPermission (err ) {
103
+ } else if os .IsNotExist (unwrapedErr ) || os .IsPermission (unwrapedErr ) {
89
104
return ErrorTypeLocalIoError
90
- } else if errors .Is (err , syscall .ECONNREFUSED ) || errors .Is (err , syscall .ECONNABORTED ) || errors .Is (err , syscall .ECONNRESET ) {
91
- return ErrorTypeCannotConnectToHost
92
- } else if errors .As (err , & syscallError ) {
93
- return ErrorTypeUnexpectedSyscallError
94
- } else if errors .Is (err , context .Canceled ) {
105
+ } else if syscallError , ok := unwrapedErr .(* os.SyscallError ); ok {
106
+ switch syscallError .Err {
107
+ case syscall .ECONNREFUSED , syscall .ECONNABORTED , syscall .ECONNRESET :
108
+ return ErrorTypeCannotConnectToHost
109
+ default :
110
+ return ErrorTypeUnexpectedSyscallError
111
+ }
112
+ } else if unwrapedErr == context .Canceled {
95
113
return ErrorTypeUserCanceled
96
- } else if errors .Is (err , http .ErrSchemeMismatch ) {
97
- return ErrorTypeProtocolError
98
- } else if errors .As (err , & tlsVerifyCertError ) {
99
- return ErrorTypeSSLError
100
- } else if errors .As (err , & urlError ) {
101
- desc := urlError .Err .Error ()
114
+ } else {
115
+ desc := unwrapedErr .Error ()
102
116
if strings .HasPrefix (desc , "tls: " ) ||
103
117
strings .HasPrefix (desc , "x509: " ) {
104
118
return ErrorTypeSSLError
@@ -108,8 +122,8 @@ func detectErrorType(err error) ErrorType {
108
122
strings .Contains (desc , "server closed idle connection" ) {
109
123
return ErrorTypeTransmissionError
110
124
}
125
+ return ErrorTypeUnknownError
111
126
}
112
- return ErrorTypeUnknownError
113
127
}
114
128
115
129
func getHttpClientName () string {
0 commit comments