Go语言 专门检查超时错误

klr1opcd  于 2023-04-03  发布在  Go
关注(0)|答案(4)|浏览(172)

我使用以下方法来检查调用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),
        },
    }
}
n3schb8v

n3schb8v1#

如果您专门查找i/o超时,则可以使用errors.Is来检测os.ErrDeadlineExceeded错误,如net包中所述:

// If the deadline is exceeded a call to Read or Write or to other
// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
// The error's Timeout method will return true, but note that there
// are other possible errors for which the Timeout method will
// return true even if the deadline has not been exceeded.

if errors.Is(err, os.ErrDeadlineExceeded) {
...

所有可能的超时仍将符合net.ErrorTimeout()正确设置。所有您需要检查的是:

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

kjthegm62#

你可以简单地向os.IsTimeout()传递一个错误,如果它是由net/http返回的超时,那么它将返回true。
func IsTimeout(err error) bool
IsTimeout返回一个布尔值,指示是否已知错误报告发生了超时。

u0njafvf

u0njafvf3#

您需要net.Error接口。http://golang.org/pkg/net/#Error

if e,ok := err.(net.Error); ok && e.Timeout() {
    // This was a timeout
} else if err != nil {
    // This was an error, but not a timeout
}

请注意,类型Asserterr.(net.Error)将正确处理nil的情况,如果nil作为错误返回,则ok值将返回false,从而使Timeout检查短路。

qyyhg6bp

qyyhg6bp4#

也可以这样做:

var timeoutError net.Error
if errors.As(err, &timeoutError); timeoutError.Timeout() {
    fmt.Println("timeout")
}

相关问题