具体检查超时错误。

huangapple go评论87阅读模式
英文:

Specifically check for timeout error

问题

我使用以下代码来检查调用webservice时是否超时,但我想要具体检查是否返回了超时错误。我该如何做呢?

我有以下代码:

// 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),
        },
    }
}

你可以在TimeoutDialer函数中检查net.DialTimeout的返回错误,如果返回的错误是超时错误,你就可以进行相应的处理。

英文:

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

答案1

得分: 89

如果你特别想要查找输入/输出超时,你可以使用errors.Is来检测一个os.ErrDeadlineExceeded错误,如net包中所述:

// 如果超过了截止时间,对Read、Write或其他I/O方法的调用将返回一个包装了os.ErrDeadlineExceeded的错误。
// 可以使用errors.Is(err, os.ErrDeadlineExceeded)进行测试。
// 错误的Timeout方法将返回true,但请注意,即使截止时间尚未超过,对于其他可能的错误,Timeout方法也将返回true。

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

所有可能的超时仍然符合net.Error,并且Timeout()被正确设置。你只需要检查:

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

If you are specifically looking for i/o timeouts, you can use errors.Is to detect an os.ErrDeadlineExceeded error as documented in the net package:

// 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) {
...

All possible timeouts will still conform to the net.Error with Timeout() set properly. All you need to check for is:

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

答案2

得分: 28

你可以直接将错误传递给os.IsTimeout(),如果它是由net/http返回的超时错误,它将返回true。

func IsTimeout(err error) bool

IsTimeout函数返回一个布尔值,指示错误是否已知为超时错误。

英文:

You can simply pass an error to os.IsTimeout() and if it's a timeout returned by net/http then it will return true.

> func IsTimeout(err error) bool
>
> IsTimeout returns a boolean indicating whether the error is known to report that a timeout occurred.

答案3

得分: 15

你需要使用net.Error接口。http://golang.org/pkg/net/#Error

if e, ok := err.(net.Error); ok && e.Timeout() {
    // 这是一个超时错误
} else if err != nil {
    // 这是一个错误,但不是超时错误
}

请注意,类型断言err.(net.Error)会正确处理nil情况,并且如果返回的错误是nil,则会将ok值设为false,从而绕过Timeout检查。

英文:

You want the net.Error interface. 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
}

Note that the type assertion err.(net.Error) will correctly handle the nil case and return false for the ok value if nil is returned as the error, short-circuiting the Timeout check.

答案4

得分: 2

这样做也是可能的:

var timeoutError net.Error
if errors.As(err, &timeoutError); timeoutError.Timeout() {
    fmt.Println("超时")
}
英文:

It's also possible by doing something like this:

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

huangapple
  • 本文由 发表于 2014年5月6日 20:36:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/23494950.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定