The Good way to close a response body

There are 3 ways people use to close a response body and I call them The Good, The Bad and The Ugly way.

The Ugly

It is not rare to find code like this:

    resp,err := http.Get("https://mysite.com")
    defer resp.Body.Close()
    if err != nil {
        // handle error    
        return err
    }

The issue with that code is that when an error will occur (err != nil), resp will be nil and the deferred instruction (resp.Body.Close()) will generate a panic.

The Bad

I found a lot of opensource projects using code like this:

    resp,err := http.Get("https://mysite.com")

    if err != nil {
        // handle error    
        return err
    }

    defer resp.Body.Close()

This code will work most of the time. However, if a redirection failure would happen, we would have bot err and resp.Body not nil and that would result in a Body leak.

The Good

The correct way to close a Body by handling all the cases is as follows:

  resp,err := http.Get("https://mysite.com")

  if resp != nil {
    defer resp.Body.Close()
  }

  if err != nil {
    // handle error    
    return err
  }