在调用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().你只需要判断一下:

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

在旧版本中,通过http包判断超时更为困难.

  • 如果达到基础连接上设置的截止日期,则可以使用Timeout()获得*net.OpError.
  • 您可以获得实现net.Error接口的tlsHandshakeTimeoutError(显然没有导出).
  • 如果url包中有问题(初始连接超时),您可以得到url.Error.
  • 如果超时设置为http.Client.Timeout[go1.3+](调用Transport.CancelRequest),则"使用闭合网络连接"可能会出错.从go1开始.5.这将正确设置超时属性.

您可以使用类型switch 判断net.Error:

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

用围棋<;1.5您需要判断错误字符串是否有http.Client超时:

if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
    fmt.Println("Could be from a Transport.CancelRequest")
}

Go相关问答推荐

调用API时使用nginx作为反向代理时从nginx获取502坏网关

GORM Find(&;Room)操作使用空数据而不是实际数据填充 struct

使用ciph.AEAD.Seal()查看内存使用情况

如何根据中间件的请求设置上下文值?获取 go-staticcheck 问题

在 Go 中将元数据从一个 JPEG 复制到另一个

我应该先解锁然后再广播吗?

Go Template if 条件

Go 中的 Azure JWT 验证不起作用

闭包所处的环境范围是什么?

使用 Grafana alert 在几分钟内重复alert

assert: mock: I don't know what to return because the method call was unexpected 在 Go 中编写单元测试时出错

使用自定义处理程序 nats golang 保留订阅方法

如何使用带有方法的字符串枚举作为通用参数?

如何将具有嵌入式 struct 的 struct 展平为 json

Go 泛型:自引用接口约束

每次有人进入我的网站时如何运行特定功能?

Go GCP 同时模拟两个服务帐户

Go:用于 XML 解码的嵌套 struct 中的提升字段

如何正确判断 io.Reader 是否为零?

Golang API 的 HTTPS