Is it possible that ioutil.ReadAll never returns an error if the variable is in memory?

I have something like the below:

func f(w http.ResponseWriter, r *http.Request) {
	data, err := ioutil.ReadAll(r.Body)
	...
}

But I was wondering if in this case it is safe not to treat err and ignore it since the r *http.Request variable is supposed to be in memory and not on the hard disk and therefore, for example, will not be denied permission to read it and therefore ioutil.ReadAll will never return an error.

Hi @Willy ,

What would you win by ignoring the error?

1 Like

@christophberger

I wouldn’t say I win but I would say I lose since if ioutil.ReadAll always returns nil doing the check becomes unnecessary then this would be fine:

data, _ := ioutil.ReadAll(r.Body)

Indeed, ignoring an error saves three lines of code, but what I mean is, what do you win by saving three lines?

If this was my code, I would simply go ahead and add the error handling. Reasons:

  • I would not have to use brain energy for working out if this one particular error handling may be unnecessary. (Yes, I have a lazy brain.)
  • The code would be prepared to catch errors that I do not expect.
  • If the internal functionality of the callee changes, it may have more reasons than before to return an error. My code would automatically be prepared for that.
  • If I change the code to a call that is more likely to return an error, I cannot forget to add error handling (because it is already there). (Yes, I am forgetful at times.)

To return to your original question, I agree it should be unlikely, if not even impossible, that ReadAll(r.Body) returns an error. It seems that an http.Request expects to receive a body of either bytes.Buffer, bytes.Reader, strings.Reader, or struct noBody type, all of which should indeed provide error-free reading experience, except maybe for io.EOF, which ReadAll turns into a nil error.

2 Likes

No, according to the documentation:

For server requests, the Request Body is always non-nil
but will return EOF immediately when no body is present.

It should do well, except in a few special circumstances; e.g., when there’s a memory limit on the goroutine handling the request, and the request body is just too large.

1 Like

There are various techniques to check this, such as:

  • check the content of the variable if have the zero value of the type
  • check the length of the variable (after case)
  • use a flag (eg isSet) to check if the variable was loaded before with some value

Not checking the errors is strongly unrecommended.

1 Like