Capture Timeout on GET request

1

In my code I have an "attempt" to catch the timeout of method Get of package http but for some reason the error is not caught and a panic is displayed saying:

  

Get link : net / http: request canceled (Client.Timeout exceeded while awaiting headers)

     

panic: runtime error: invalid memory address or nil pointer dereference

This request happens within a goroutine .

request, err := http.NewRequest(method, endpoint, bytes.NewReader(data)) // data é nil
if err != nil {
    return nil, err
}

client := &http.Client{
    Timeout: 2 * time.Second,
}

response, err := client.Do(request)
if err != nil {
    fmt.Println(err.Error())
    return nil, Error{Message: err.Error(), Code: response.StatusCode}
}
defer response.Body.Close()

// TODO: For some reason the timeout handle is not working
if err, ok := err.(net.Error); ok && err.Timeout() {
    fmt.Println("timeout!") // não exibe a mensagem
    return nil, Error{Message: "timeout.", Code: http.StatusRequestTimeout}
}

When I return Error I make a type checking with:

if err, ok := err.(commom.Error); ok {
    close(tube) // close the channel
    w.WriteHeader(err.Code)
    response.Encode(err)
    return
}
    
asked by anonymous 18.09.2018 / 15:23

1 answer

1

The error occurred because another error was verified before the error of timeout

response, err := client.Do(request)
if err != nil {
    fmt.Println(err.Error())
    return nil, Error{Message: err.Error(), Code: response.StatusCode}
}

In the above case the variable response did not have StatuCode because client ended the request due to timeout time.

The correct order of error checking is:

response, err := client.Do(request)
if err, ok := err.(net.Error); ok && err.Timeout() {
    return nil, Error{Message: "timeout.", Code: http.StatusRequestTimeout}
}
defer response.Body.Close()

if err != nil {
    fmt.Println(err.Error())
    return nil, Error{Message: err.Error(), Code: response.StatusCode}
}
    
24.09.2018 / 15:37