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
Closed

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

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

Comments

@tv42
Copy link

tv42 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
Copy link

arvenil commented Mar 31, 2015

In which version of go this got fixed?

@minux
Copy link
Member

minux commented Mar 31, 2015 via email

@mikioh mikioh added this to the Go1.5 milestone Apr 1, 2015
dropwhile added a commit to cactus/go-camo that referenced this issue Aug 28, 2015
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
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
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.
Projects
None yet
Development

No branches or pull requests

5 participants