I am aware that the WriteHeader
method of http.ResponseWriter can only be called once per HTTP response, can only have a single response status code and can only send the headers once. This is all perfectly fine.
The question is, how should I refactor my code in order to override 201
and return 500
if http.ResponseWriter.Write
returns an error? As you can see below I force panic on purpose to see how httprouter.Router.PanicHandler handles it. As expected, logs show http: superfluous response.WriteHeader call from ...
and the response is 201
because it is too late as explained above.
package server
import (
"github.com/julienschmidt/httprouter"
"log"
"net/http"
)
func Serve() {
rtr := httprouter.New()
rtr.GET("/", home.Welcome)
handle500(rtr)
err := http.ListenAndServe(":8080", rtr)
if err != nil {
log.Fatalf("server crash")
}
}
func handle500(r *httprouter.Router) {
r.PanicHandler = func(res http.ResponseWriter, req *http.Request, err interface{}) {
res.WriteHeader(http.StatusInternalServerError)
// http: superfluous response.WriteHeader call from line above
}
}
package home
import (
"github.com/julienschmidt/httprouter"
"net/http"
)
func Welcome(res http.ResponseWriter, _ *http.Request, _ httprouter.Params) {
// doing a few bits and building the body
res.Header().Set("Content-Type", "application/json")
res.WriteHeader(201)
_, err := res.Write("body goes here")
if err == nil { // I am doing this deliberately to test 500
panic("assume that something has gone wrong with res.Write and an error occurred")
}
}
There is no way to "override" the status code as it's sent to the browser immediately.
You're checking for the return value of http.ResponseWriter.Write()
. I'm not sure this is a good strategy. If writing the response failed then chances are that writing more will probably fail, too.
Logging the failure seems more appropriate, but I would expect most failures to be dropped connections and other errors which won't require action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With