// c.send() always closes req.Body
reqBodyClosed = true
if !deadline.IsZero() && didTimeout() {
- err = &httpError{
- err: err.Error() + " (Client.Timeout exceeded while awaiting headers)",
- timeout: true,
- }
+ err = &timeoutError{err.Error() + " (Client.Timeout exceeded while awaiting headers)"}
}
return nil, uerr(err)
}
return n, err
}
if b.reqDidTimeout() {
- err = &httpError{
- err: err.Error() + " (Client.Timeout or context cancellation while reading body)",
- timeout: true,
- }
+ err = &timeoutError{err.Error() + " (Client.Timeout or context cancellation while reading body)"}
}
return n, err
}
} else if !ne.Timeout() {
t.Errorf("net.Error.Timeout = false; want true")
}
+ if !errors.Is(err, context.DeadlineExceeded) {
+ t.Errorf("ReadAll error = %q; expected some context.DeadlineExceeded", err)
+ }
if got := ne.Error(); !strings.Contains(got, "(Client.Timeout") {
if runtime.GOOS == "windows" && strings.HasPrefix(runtime.GOARCH, "arm") {
testenv.SkipFlaky(t, 43120)
if !ne.Timeout() {
t.Error("net.Error.Timeout = false; want true")
}
+ if !errors.Is(err, context.DeadlineExceeded) {
+ t.Errorf("ReadAll error = %q; expected some context.DeadlineExceeded", err)
+ }
if got := ne.Error(); !strings.Contains(got, "Client.Timeout exceeded") {
if runtime.GOOS == "windows" && strings.HasPrefix(runtime.GOARCH, "arm") {
testenv.SkipFlaky(t, 43120)
if g, w := ue.Err, wantErr; g != w {
t.Errorf("url.Error.Err = %v; want %v", g, w)
}
+ if got := errors.Is(err, context.DeadlineExceeded); got != wantIsTimeout {
+ t.Errorf("errors.Is(err, context.DeadlineExceeded) = %v, want %v", got, wantIsTimeout)
+ }
})
}
}
continueCh <-chan struct{}
}
-type httpError struct {
- err string
- timeout bool
+// httpTimeoutError represents a timeout.
+// It implements net.Error and wraps context.DeadlineExceeded.
+type timeoutError struct {
+ err string
}
-func (e *httpError) Error() string { return e.err }
-func (e *httpError) Timeout() bool { return e.timeout }
-func (e *httpError) Temporary() bool { return true }
+func (e *timeoutError) Error() string { return e.err }
+func (e *timeoutError) Timeout() bool { return true }
+func (e *timeoutError) Temporary() bool { return true }
+func (e *timeoutError) Is(err error) bool { return err == context.DeadlineExceeded }
-var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
+var errTimeout error = &timeoutError{"net/http: timeout awaiting response headers"}
// errRequestCanceled is set to be identical to the one from h2 to facilitate
// testing.