Description
What version of Go are you using (go version
)?
$ go version go version go1.14.1 darwin/amd64
Does this issue reproduce with the latest release?
Yep
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="..." GOCACHE="/Users/.../Library/Caches/go-build" GOENV="/Users/.../Library/Application Support/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOINSECURE="" GONOPROXY="" GONOSUMDB="" GOOS="darwin" GOPATH="/Users/.../gopath" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64" GCCGO="gccgo" AR="ar" CC="..." CXX="clang++" CGO_ENABLED="1" GOMOD="..." 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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/2b/74fz3jhd4wz4vnbf4z7ywzww0000gp/T/go-build135874009=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
https://play.golang.org/p/CsZfrDwLeFb
What did you expect to see?
An error I could inspect.
What did you see instead?
A *url.Error
with its Err
set to errors.New(...)
.
In certain environments we use HTTP CONNECT, and on occasion some of the destination servers are temporarily unreachable. When this happens with other proxies, we can inspect the HTTP response (status codes and/or headers) or the error (does Temporary report true?) to determine whether we should backoff and retry the request.
However, net/http inspects the response from the initial CONNECT request and if it's anything other than 200, it returns an generic error constructed from the status code text:
Line 1622 in 564c76a
This means we're limited to something like
var (
httpStatusServiceUnavailable = http.StatusText(http.StatusServiceUnavailable)
...
)
resp, err := c.Get(...)
if err != nil {
switch s := err.(*url.Error).Err.Error(); s {
case httpStatusServiceUnavailable:
/* backoff then retry */
...
default:
return err
}
}
...
An example of a useful error would be something like
type ConnectError struct {
StatusCode int
...
}
func (c *ConnectError) Error() string {
return StatusText(c.StatusCode)
}
var _ error = (*ConnectError)(nil)