调用Web服务时,我使用以下方法检查超时,但是我想专门检查是否返回超时错误。我该怎么做:S
我有这个:
// Timeout type Timeout struct { Connect time.Duration ReadWrite time.Duration } // TimeoutDialer func TimeoutDialer(timeout *Timeout) func(net, addr string) (c net.Conn, err error) { return func(netw, addr string) (net.Conn, error) { conn, err := net.DialTimeout(netw, addr, timeout.Connect) if err != nil { return nil, err } conn.SetDeadline(time.Now().Add(timeout.ReadWrite)) return conn, nil } } // HttpClient func HttpClient(config Config) *http.Client { to := &Timeout{ Connect: time.Duration(config.MaxWait) * time.Second, ReadWrite: time.Duration(config.MaxWait) * time.Second, } return &http.Client{ Transport: &http.Transport{ Dial: TimeoutDialer(to), }, } }
作为go1.6的,从超时所有错误应符合net.Error与Timeout()正确设置。您需要检查的只是:
net.Error
Timeout()
if err, ok := err.(net.Error); ok && err.Timeout() {
在旧版本中,通过http包检查超时更为困难。
*net.OpError
tlsHandshakeTimeoutError
url.Error
http.Client.Timeout
Transport.CancelRequest
您可以net.Error使用类型开关检查a :
switch err := err.(type) { case net.Error: if err.Timeout() { fmt.Println("This was a net.Error with a Timeout") } case *url.Error: fmt.Println("This is a *url.Error") if err, ok := err.Err.(net.Error); ok && err.Timeout() { fmt.Println("and it was because of a timeout") } }
当go <1.5时,您将需要检查错误字符串是否http.Client超时:
http.Client
if err != nil && strings.Contains(err.Error(), "use of closed network connection") { fmt.Println("Could be from a Transport.CancelRequest") }