Should I check the Close () error on the response body?

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 error , but is not checked. Is something missing here? The importance of checking for each error is often emphasized in go, but I often see this defer resp.Body.Close() pattern without error checking.

+5
source share
3 answers

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

In most cases, to close the body of the answer, the answer to both questions is absolutely nothing. If you would not have done anything, if an error had occurred and the error had no noticeable effect, there is no reason to check it.

Also note that Close() returns an error to execute the io.Closer interface; the function does not necessarily return an error. You will need to check the source to see if it has an error.

+8
source

This is minus using defer

As a responsible developer, it is recommended that you check all possible points prone to errors and process them as gracefully as you can.

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

Option number 1

Do not use defer , instead manually call close as soon as you are done with the response body, and just check for errors.

Option number 2

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

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

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


Further information can be found here.

+4
source

To add @Mihailo option # 2, call it option # 2.1 Define the dclose() function as follows:

 func dclose(c io.Closer) { if err := c.Close(); err != nil { log.Fatal(err) } } 

use like this:

 defer dclose(resp.Body) 

Also in your code, checking for err!=nil may declare:

 func errcheck(err error) { if err != nil { log.Fatal(err) } } 

then use:

 errcheck(err) 

then your code will look like this:

 resp, err := http.Get("http://example.com/") errcheck(err) defer dclose(resp.Body) body, err := ioutil.ReadAll(resp.Body) errcheck(err) fmt.Printf("%s", string(body)) 

IMHO a little cleaner, maybe? But I'll wait for the go fan to fix me and highlight the flaws.

EDIT

Thanks! @RayfenWindspear

Replace log.Fatal(err) with log.Println(err) to avoid unnecessary panic.

EDIT2

dclose() to avoid confusion with go close()

Good luck

+2
source

Source: https://habr.com/ru/post/1273370/


All Articles