Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: errors from Client.Timeout triggering have .Timeout()==false #9405

Closed
tv42 opened this issue Dec 19, 2014 · 2 comments

Comments

Projects
None yet
5 participants
@tv42
Copy link

commented Dec 19, 2014

(From aaronlevy on IRC)

It's hard for a client to know when a HTTP request failed due to timeout, and when for other reasons.

Given a slow server

package main

import (
    "fmt"
    "net/http"
    "time"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        time.Sleep(3*time.Second)
        fmt.Fprintf(w, "req rcvd")
    })
    http.ListenAndServe(":8080", nil)
}

and a client

package main

import (
    "fmt"
    "io/ioutil"
    "net"
    "net/http"
    "net/url"
    "time"
)

func main() {
    client := &http.Client{
        Timeout: time.Duration(time.Second),
    }

    req, err := client.Get("http://localhost:8080")
    if err != nil {
        fmt.Printf("type: %T\n", err)
        fmt.Printf("error: %v\n", err)
        if err2, ok := err.(*url.Error); ok {
            fmt.Printf("inner type: %T\n", err2.Err)
            fmt.Printf("inner error: %v\n", err2.Err)
            if err3, ok := err2.Err.(net.Error); ok {
                fmt.Printf("is timeout: %v\n", err3.Timeout())
            }
            if err4, ok := err2.Err.(*net.OpError); ok {
                fmt.Printf("OpError inner type: %T\n", err4.Err)
                fmt.Printf("OpError inner error: %v\n", err4.Err)
            }
        }
        return
    }

    resp, err := ioutil.ReadAll(req.Body)
    req.Body.Close()
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf("%s", resp)
}

Results in

$ go run server.go &
$ go run client.go
type: *url.Error
error: Get http://localhost:8080: read tcp 127.0.0.1:8080: use of closed network connection
inner type: *net.OpError
inner error: read tcp 127.0.0.1:8080: use of closed network connection
is timeout: false
OpError inner type: *errors.errorString
OpError inner error: use of closed network connection

That's quite the gift wrapping on that error. But the real bug is "is timeout: false". The error was caused by a timeout, it should claim to be one.

@arvenil

This comment has been minimized.

Copy link

commented Mar 31, 2015

In which version of go this got fixed?

@minux

This comment has been minimized.

Copy link
Member

commented Mar 31, 2015

@mikioh mikioh added this to the Go1.5 milestone Apr 1, 2015

cactus added a commit to cactus/go-camo that referenced this issue Aug 28, 2015

updates for golang 1.5
It seems[1] go http.Client errors changed a bit for go 1.5.

[1]: golang/go#9405

stefanschneider added a commit to stefanschneider/rep that referenced this issue Sep 22, 2015

Update client test to mach go 1.5 http errors
Go 1.5 will return a different error message for http timeout.
Ref: golang/go#9405

stefanschneider added a commit to stefanschneider/rep that referenced this issue Sep 22, 2015

Update client test to mach go 1.5 http errors
Go 1.5 will return a different error message for http timeout.
Ref: golang/go#9405

@golang golang locked and limited conversation to collaborators Jun 25, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.