dspx15491 2014-05-06 12:36
浏览 23
已采纳

具体检查超时错误

I use the following to check for timeouts when calling a webservice, but I would like to check specifically if there is a timeout error returned. How do I do that :S

I have this:

// 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),
        },
    }
}
  • 写回答

3条回答 默认 最新

  • douchan7552 2014-05-06 14:21
    关注

    As of go1.6, all errors from timeouts should conform to net.Error with Timeout() set properly. All you need to check for is:

    if err, ok := err.(net.Error); ok && err.Timeout() {
    

    In older versions, checking for timeout through the http package was more difficult.

    • You can get a *net.OpError with Timeout() if you hit a Deadline set on the underlying connection.
    • You can get a tlsHandshakeTimeoutError (which is obviously not exported) that implements the net.Error interface.
    • You can get a url.Error, if there was a problem within the url package (timeout during initial connection)
    • You can get an error with "use of closed network connection" if you hit a timeout set with http.Client.Timeout[go1.3+] (which calls Transport.CancelRequest). As of go1.5, this will have the Timeout property set correctly.

    You could check for a net.Error with a type switch:

    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")
        }
    }
    

    With go < 1.5 you will need to check the error string for an http.Client timeout:

    if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
        fmt.Println("Could be from a Transport.CancelRequest")
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp
  • ¥15 自己做的代码上传图片时,报错
  • ¥15 Lingo线性规划模型怎么搭建
  • ¥15 关于#python#的问题,请各位专家解答!区间型正向化
  • ¥15 unity从3D升级到urp管线,打包ab包后,材质全部变紫色
  • ¥50 comsol温度场仿真无法模拟微米级激光光斑
  • ¥15 上传图片时提交的存储类型
  • ¥15 VB.NET如何绘制倾斜的椭圆
  • ¥15 arbotix没有/cmd_vel话题