-2

My API needs to parse incoming requests. In the first step, the data needs to be read by Go's ReadAll() function of the ioutil package. Why should there an error occur?

The official documentation does not give a hint, because the reasons for such an error aren't described.

func ParseRequest(w http.ResponseWriter, r *http.Request) {
    body, err := ioutil.ReadAll(r.Body)

    if err != nil {
        // handle the error
    }
}
icza
  • 389,944
  • 63
  • 907
  • 827
user3147268
  • 1,814
  • 7
  • 26
  • 39
  • *Why* can the body not be read? Is it not valid JSON? Does the server code contain an error? –  May 02 '15 at 17:14
  • Something like this will happen unlikely but Go's standard library will not offer an error as a potential return value if there's no reason as you can see in the [official docs](https://golang.org/pkg/io/ioutil/#ReadAll). – user3147268 May 02 '15 at 17:17

2 Answers2

4

ioutil.ReadAll can fail for many reasons. It is capable of reading any io.Reader, not just an HTTP request body. And Request.Body is just an io.ReadCloser. It is totally legal for me to generate one that is tied to things other than the network socket (I do these kinds of things to http all the time to build proxies and tunneling protocols).

It should be obvious that many kinds of io.Reader events can have errors (you may not have access to a file for instance, or the disk may be unmounted half-way through reading it). Specific to HTTP, you might similarly expect network failure errors. What would you expect to happen if the network socket received a RST packet half-way through reading the request body?

Ultimately, though, the point you should take away is that you must deal with errors because the Reader interface can generate errors. Do not make assumptions about how that interface is implemented.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thanks for explaining this. Can the sending client cause any errors? I am asking because I want to implement an API and want to return a http status code. – user3147268 May 02 '15 at 18:12
  • I'm not certain what you mean here. A status code isn't an error; it's just a int. If you're asking whether you can set the status code, that's just `ResponseWriter.WriteHeader()`. – Rob Napier May 02 '15 at 19:39
  • I want to return an http status code, if `ReadAll` returns an error. But what is the correct status code? Either an internal server error (500) or a bad request (400) caused by the client. – user3147268 May 02 '15 at 19:45
  • Thanks for the help. That's what I finally wanted to know :) – user3147268 May 02 '15 at 20:23
  • Another point of failure might be when your `r.Body` is wrapped with, for example, data decompressor – it would than fail if stream is not a valid (say) gzip. For this purpose it might be better to send 400. – tomasz May 02 '15 at 20:44
0

If the client did send invalid JSON, it is the clients fault: 400 Bad Request.

If the JSON was valid but the server code contains a bug, its the servers fault: 500 Internal Server error.

  • Before I can validate the JSON I need to make the request **readable**. A 404-status will be send **afterwards**. I don't think that the Go standard-libary will contain such an error, so it will unlikely be the fault of the server aka. Go's package. The question, why the an error could be returned by the functions, remains open. – user3147268 May 02 '15 at 17:22
  • I don't talk about 404 but 400. BTW: Is your question about REST and an API or about a Go implementation? –  May 02 '15 at 17:23
  • The reason, why such an error is included in Go and what reason could cause it, will answer the question about the statuscode. So it would have it focus on Go's implementation. And I ment a 400-Error during the validation. My fault. – user3147268 May 02 '15 at 17:26
  • 2
    Then please edit your question to make it more clear. –  May 02 '15 at 17:28
  • I updated the question and removed the rest api part. – user3147268 May 02 '15 at 17:32