我有一些代码可以通过 MultipartUpload 将文件上传到某个 S3 存储桶。如果服务器不可用,代码会产生如下错误:
operation error S3: CreateMultipartUpload, https response error StatusCode: 0, RequestID: , HostID: , request send failed, Post "http://[...]?uploads=&x-id=CreateMultipartUpload": dial tcp xx.xx.x.xxx:xx: i/o timeout
错误由
s3.Client.CreateMultipartUpload
返回。请注意,我正在使用 aws-sdk-go-v2
。
我想识别此类超时错误,但仅超时错误。需要明确的是,我不想修复错误,我只是想能够确定它发生了。除了解析
i/o timeout
的错误字符串之外,还有其他更优雅的方法吗?
我尝试过以下一些方法,但都不起作用:
var oe *smithy.OperationError
if errors.As(err, &oe) {
fmt.Printf("Attempt 1 %t\n", errors.Is(err, os.ErrDeadlineExceeded))
fmt.Printf("Attempt 2 %t\n", errors.Is(oe.Unwrap(), os.ErrDeadlineExceeded))
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
fmt.Printf("Attempt 3\n")
}
if netErr, ok := oe.Unwrap().(net.Error); ok && netErr.Temporary() {
fmt.Printf("Attempt 4\n")
}
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
fmt.Printf("Attempt 3\n")
}
if netErr, ok := oe.Unwrap().(net.Error); ok && netErr.Timeout() {
fmt.Printf("Attempt 4\n")
}
fmt.Printf("Attempt 5 %t\n", os.IsTimeout(err))
fmt.Printf("Attempt 6 %t\n", os.IsTimeout(oe.Unwrap()))
}
如果链中的每个函数调用都包装了它们返回的错误,那么这就足够了:
if errors.Is(err, os.ErrDeadlineExceeded) {
// it's an i/o timeout
}
但是,如果链中某处的一个调用没有包装错误,因为它是 <1.10, then it won't work. If it doesn't work, there's a <1.13 function that will probably work:
IsTimeout(err)
:
if errors.Is(err, os.ErrDeadlineExceeded) || os.IsTimeout(err) {
// it's an i/o timeout
}