mirror of
https://github.com/golang/go.git
synced 2025-05-19 06:14:40 +00:00
net/http: wrap client errors
Fixes #50856 Change-Id: I7fe89fcce223e1571debb73436f8aeb3bfbe4b9f GitHub-Last-Rev: be570e7883be06adbd227a1dfe63a80e384d96f6 GitHub-Pull-Request: golang/go#63448 Reviewed-on: https://go-review.googlesource.com/c/go/+/533119 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: qiulaidongfeng <2645477756@qq.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
c51beb4342
commit
67d30fc315
@ -726,7 +726,7 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
|
|||||||
reqBodyClosed = true
|
reqBodyClosed = true
|
||||||
if !deadline.IsZero() && didTimeout() {
|
if !deadline.IsZero() && didTimeout() {
|
||||||
err = &httpError{
|
err = &httpError{
|
||||||
err: err.Error() + " (Client.Timeout exceeded while awaiting headers)",
|
err: fmt.Errorf("%w (Client.Timeout exceeded while awaiting headers)", err),
|
||||||
timeout: true,
|
timeout: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -969,7 +969,7 @@ func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
if b.reqDidTimeout() {
|
if b.reqDidTimeout() {
|
||||||
err = &httpError{
|
err = &httpError{
|
||||||
err: err.Error() + " (Client.Timeout or context cancellation while reading body)",
|
err: fmt.Errorf("%w (Client.Timeout exceeded or context cancellation while reading body)", err),
|
||||||
timeout: true,
|
timeout: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2127,3 +2127,22 @@ func testProbeZeroLengthBody(t *testing.T, mode testMode) {
|
|||||||
t.Fatalf("server got body %q, want %q", gotBody, content)
|
t.Fatalf("server got body %q, want %q", gotBody, content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClientTimeoutReturnsContextDeadlineExceeded(t *testing.T) {
|
||||||
|
run(t, testClientTimeoutReturnsContextDeadlineExceeded)
|
||||||
|
}
|
||||||
|
func testClientTimeoutReturnsContextDeadlineExceeded(t *testing.T, mode testMode) {
|
||||||
|
doneCh := make(chan struct{})
|
||||||
|
defer close(doneCh)
|
||||||
|
cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
|
<-doneCh
|
||||||
|
w.WriteHeader(200)
|
||||||
|
}))
|
||||||
|
// check that, upon exceeding Client.Timeout, the returned error is context.DeadlineExceeded.
|
||||||
|
cst.c.Timeout = 1 * time.Millisecond
|
||||||
|
req, _ := NewRequest("GET", cst.ts.URL, nil)
|
||||||
|
_, err := cst.c.Do(req)
|
||||||
|
if !errors.Is(err, context.DeadlineExceeded) {
|
||||||
|
t.Fatalf("expected context.DeadlineExceeded, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2556,15 +2556,17 @@ type writeRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type httpError struct {
|
type httpError struct {
|
||||||
err string
|
err error
|
||||||
timeout bool
|
timeout bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *httpError) Error() string { return e.err }
|
func (e *httpError) Error() string { return e.err.Error() }
|
||||||
func (e *httpError) Timeout() bool { return e.timeout }
|
func (e *httpError) Timeout() bool { return e.timeout }
|
||||||
func (e *httpError) Temporary() bool { return true }
|
func (e *httpError) Temporary() bool { return true }
|
||||||
|
func (e *httpError) Is(target error) bool { return errors.Is(e.err, target) }
|
||||||
|
func (e *httpError) Unwrap() error { return e.err }
|
||||||
|
|
||||||
var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
|
var errTimeout error = &httpError{err: errors.New("net/http: timeout awaiting response headers"), timeout: true}
|
||||||
|
|
||||||
// errRequestCanceled is set to be identical to the one from h2 to facilitate
|
// errRequestCanceled is set to be identical to the one from h2 to facilitate
|
||||||
// testing.
|
// testing.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user