Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error handling with http.NewRequest in Go

Tags:

http

go

I was using http.NewRequest to make a GET Request.

I deliberately tried to tamper the API url just to check if my err handling works.

But its not working as expected . In err value is returned and I am unable to compare it.

    jsonData := map[string]string{"firstname": "Nic", "lastname": "Raboy"}
    jsonValue, _ := json.Marshal(jsonData)    
request, err := http.NewRequest("POST", "http://httpbin.org/postsdf", bytes.NewBuffer(jsonValue))


        request.Header.Set("Content-Type", "application/json")
        client := &http.Client{}
        response, err := client.Do(request)

        if err != nil {
            fmt.Println("wrong")

        } else {
            data, _ := ioutil.ReadAll(response.Body)
            fmt.Println(string(data))
        }

The output is as below:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>

But I am expecting to print "Wrong".

like image 343
Balakumar Ezhilmaran Avatar asked Mar 17 '19 18:03

Balakumar Ezhilmaran


2 Answers

The HTTP call succeeds (the call went through to the server, and response came back), that's why err is nil. It's just that the HTTP status code is not http.StatusOK (but by judging the response document, it's http.StatusNotFound).

You should check the HTTP status code like this:

response, err := client.Do(request)
if err != nil {
    fmt.Println("HTTP call failed:", err)
    return
}
// Don't forget, you're expected to close response body even if you don't want to read it.
defer response.Body.Close()

if response.StatusCode != http.StatusOK {
    fmt.Println("Non-OK HTTP status:", response.StatusCode)
    // You may read / inspect response body
    return
}

// All is OK, server reported success.

Also note that certain API endpoints might return other than http.StatusOK for success, such as HTTP 201 - Created, or HTTP 202 - Accepted etc. If you want to check all success status codes, you can do it like this:

// Success is indicated with 2xx status codes:
statusOK := response.StatusCode >= 200 && response.StatusCode < 300
if !statusOK {
    fmt.Println("Non-OK HTTP status:", response.StatusCode)
    // You may read / inspect response body
    return
}
like image 143
icza Avatar answered Oct 09 '22 16:10

icza


you should user the status code, you can also write a small handler for every http request that you create.

response, err := client.Do(request)
        switch response.StatusCode {
        case 200:
            fmt.Println("work!")
            break
        case 404:
            fmt.Println("not found!")
            break
        default:
            fmt.Println("http", response.Status)
        }
like image 37
Or Yaacov Avatar answered Oct 09 '22 15:10

Or Yaacov