golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.98k stars 17.67k forks source link

net/http: Client does not wrap context errors #50856

Closed soypat closed 8 months ago

soypat commented 2 years ago

What version of Go are you using (go version)?

$ go version
go version go1.17.3 linux/amd64

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN="/home/pato/go/bin"
GOCACHE="/home/pato/.cache/go-build"
GOENV="/home/pato/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/pato/go/pkg/mod"
GONOPROXY="github.com/LIA-Aerospace"
GONOSUMDB="github.com/LIA-Aerospace"
GOOS="linux"
GOPATH="/home/pato/go"
GOPRIVATE="github.com/LIA-Aerospace"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.3"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/pato/src/lia/gptos/_gui/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3992144195=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Issue not reproducible on go playground. https://go.dev/play/p/NfEhKnRBFuv

// You can edit this code!
// Click here and start typing.
package main

import (
    "bytes"
    "context"
    "encoding/json"
    "errors"
    "fmt"
    "net/http"
    "time"
)

func main() {
    client := http.Client{
        Timeout: 1 * time.Millisecond,
    }
    b, err := json.Marshal(&struct{}{})
    if err != nil {
        panic(err)
    }
    _, err = client.Post("http://google.com", "application/json; charset=UTF-8", bytes.NewBuffer(b))
    if err != nil {
        switch {
        case errors.Is(err, context.DeadlineExceeded):
            fmt.Println("server took too long!") // Expected output
            return
        }
        panic("unexpected:" + err.Error())
    }
    fmt.Println("all good :)")
}

What did you expect to see?

server took too long!

What did you see instead?

panic: unexpected:Post "http://google.com": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

goroutine 1 [running]:
main.main()
        /home/pato/src/test/main.go:29 +0x1ac
exit status 2

This is because the errors are wrapped like this:

(type:*url.Error):Post "http://google.com": context deadline exceeded (Client.Timeout exceeded while awaiting headers)(type:*http.httpError):context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Second error could easily wrap context.DeadlineExceeded

mknyszek commented 2 years ago

CC @neild

gopherbot commented 2 years ago

Change https://golang.org/cl/381694 mentions this issue: net/http: Client wraps context errors

gopherbot commented 1 year ago

Change https://go.dev/cl/533119 mentions this issue: net/http: wrap client errors

cherrymui commented 9 months ago

Reopen. CL reverted.

gopherbot commented 9 months ago

Change https://go.dev/cl/559035 mentions this issue: net/http: wrap client errors

gopherbot commented 8 months ago

Change https://go.dev/cl/567537 mentions this issue: net/http: make timeout errors match context.DeadlineExceeded