英文:
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")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论