I was going through https://blog.golang.org/error-handling-and-go and at the end it gave a good example on how to handle returning errors in a cleaner way and just made something simple:
// Wrapper for handler functions.
type rootHandler func(http.ResponseWriter, *http.Request) error
// Implement the http.Handler interface.
func (fn rootHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := fn(w, r) // Call handler function.
if err == nil {
return
}
...
}
// POST /api/test/
testRouter.
Handle("/", rootHandler(create)).
Methods("POST")
// GET /api/test/{id}/
testRouter.
HandleFunc("/{id:[0-9]+}/", rootHandler(getByID)).
Methods("GET")
func create(w http.ResponseWriter, r *http.Request) error {
// CustomError implementes error
return &CustomError{
Kind: EPARSE,
Status: http.StatusBadRequest,
Message: "some message",
Op: "create",
Err: err,
}
}
This worked very well, but I would prefer not to wrap every controller method (create
in this case) in rootHandler
, and figured the best way is to figure out some sort of post-middleware. I've failed at trying to create a post-middlewhere which the router uses instead of each controller method, and wondering how you may go about implementing this. The closest answer on SO I could find was emmbee's answer on How can I combine Go middleware pattern with error returning request handlers? except for fn in AuthMiddleware would be a controller method.
So ideally, I would have the below handler which handles the CustomError
if it exists
// POST /api/test
testRouter.
Handle("/", create).
Methods("POST")
For context, I'm using gorilla mux and negroni.
Any ideas are appreciated! Thank you very much.