Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I error-check Close() on a response body?

Tags:

The docs for net/http have the following example:

resp, err := http.Get("http://example.com/")
if err != nil {
    panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Printf("%s", body)

Close returns an error, but it is not checked. Is there something I'm missing here? The importance of checking every error is frequently emphasized in go, but I see this defer resp.Body.Close() pattern a lot with no error checks.

like image 699
rcorre Avatar asked Nov 14 '17 19:11

rcorre


People also ask

How do you close a response body?

Use the defer method to close the response body. This is done to make sure that the response body gets closed even in case of runtime error during reading and parsing of response.

Should check returned error before deferring file close()?

It's important to check for errors when closing a file, even in a deferred function. Running the program confirms that the file is closed after being written.

What does defer resp body close do?

defer resp.Body.Close() In the Go sample, if the "ParseResponse" call returns an error (and the function returns "early"), the "defer" will ensure that the response body will be closed. If the "ParseResponse" call is successful, then the "defer" will ensure that the response body will be closed.


2 Answers

There are two things to consider: What would you do with it if you checked it and there was an error? And, what would the side-effects be if there was an error?

In most cases, for closing a response body, the answer to both questions is... absolutely nothing. If there's nothing you'd do if there was an error and the error has no appreciable impact, there's no reason to check it.

Also note that Close() returns an error in order to fulfill the io.Closer interface; the function doesn't necessarily return an error. You'd need to check the source to know for sure if it has an error case.

like image 155
Adrian Avatar answered Oct 15 '22 13:10

Adrian


This is a downside of using defer

It would be advised, as a responsible developer, that you check for all possible error prone points, and handle them as gracefully as you can.

Here are some of the options you can choose in handling this situation:

Option #1

Do not use defer, instead manually call close once you're done with the response's body and simply check for errors then.

Option #2

Create an anonymous function that wraps the closing and error checking code. Something like this:

defer func() {
    err := resp.Body.Close()
    if err != nil {
        log.Fatal(err)
    }
}()

Avoid using panics in your programs. Try to handle the errors gracefully by doing something or at least logging the error.


Additional information can be found here.

like image 23
Mihailo Avatar answered Oct 15 '22 13:10

Mihailo