2

I have a HandleFunc, which in case of success, I want (apparently) to be able to

  • sent a 200 response
  • write an informative message in the response

However the following snippet (executed in the happy path)

    if fullRun {
        w.Write([]byte(successMsg))
        w.WriteHeader(http.StatusOK)
    }

is causing this message in my application logs

http: superfluous response.WriteHeader

why is that?

Is there another pattern/practice to be followed when trying to both return 200 as also a (text) message?

pkaramol
  • 16,451
  • 43
  • 149
  • 324

1 Answers1

10

From the documentation for WriteHeader:

If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly used to send error codes.

So your first write call already calls WriteHeader, and your second call is ignored.

Call WriteHeader before you write the body, or don't call it if all you're sending is StatusOK.

Burak Serdar
  • 46,455
  • 3
  • 40
  • 59
  • but its a funky design because we can check for errors when writing the body. What if we want to set the status code only after we know it wasnt an error or maybe want to set an error code if there was an error? Trying to write the body already set the header so its hard to change after we know if it was an error or not. I am talking about something like `err := json.NewEncoder(w).Encode(data)`. – The Fool Dec 30 '21 at 23:11
  • This is not related to the design of the language. HTTP status is returned in the header, so once you send the header, there is no way you can go back and change that. If JSON marshaling fails during write, it is either a network error, or you have a runtime error on your end. The client may detect the network error, but not the runtime error. – Burak Serdar Dec 30 '21 at 23:23