Hi, I have bunch of handlers who writes json or error based on lot of validations etc.
Because of that, my handlers got lot of returns and function if…else conditions. Currently I have my code composed this way:
There was a similar question on the mailing list recently as well, but your example is a little more complete, so I can be more verbose. No promises that this will compile, but it should be close (not in front of my own machine right now)
type HTTPError struct {
Status int
Err error
}
func (e *HTTPError) Error() string {
// Simplified
return fmt.Sprintf("HTTP %d: %s", e.Status, e.Err)
}
type ClusterHandler struct {
Handler func(Cluster, http.ResponseWriter, *http.Request) error
C Cluster
}
func (ch ClusterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := ch.H(ch.C, w, r)
if err != nil {
switch e := err.(type) {
case *HTTPError:
log.Println(e)
respondWith(w, e.Status, e.Err)
return
default:
// fall back to a HTTP 500 for unspecified errors
log.Println(err)
respondWith(w, 500, nil)
return
}
}
}
// Call it with http.Handle("/cluster", ClusterHandler{getFrom, Cluster})
func getFrom(cluster Cluster, w http.ResponseWriter, r *http.Request) error {
ID, err := GetIDFromString(mux.Vars(r)["kid"])
if err != nil {
return &HTTPError(400, err)
}
results, err := PollFrom()
if err != nil {
return &HTTPError(500, err)
}
// You could also modify respondWith to return an error and then just
// return respondWith(w, http.StatusOK, results)
// respondWith could then write to a temporary buffer (pooled) to catch any JSON
// marshalling errors before writing to the response.
respondWith(w, http.StatusOK, results)
return nil
}
This worked flawlessly with very small changes. I made some changes and will be making some changes to respond with, but this is what I was looking for.