package handler import ( "log" "net/http" ) // badRequest is handled by setting the status code in the reply to StatusBadRequest. type badRequest struct{ error } // notFound is handled by setting the status code in the reply to StatusNotFound. type notFound struct{ error } // notAuthorized is handled by setting the status code in the reply to StatusNotAuthorized. type notAuthorized struct{ error } // notImplemented is handled by setting the status code in the reply to StatusNotImplemented. type notImplemented struct{ error } // forbidden is handled by setting the status code in the reply to StatusForbidden. type forbidden struct{ error } // internalServerError is handled by setting the status code in the reply to StatusInternalServerError. type internalServerError struct{ error } // errorHandler wraps a function returning an error by handling the error and returning a http.Handler. // If the error is of the one of the types defined above, it is handled as described for every type. // If the error is of another type, it is considered as an internal error and its message is logged. func errorHandler(f func(w http.ResponseWriter, r *http.Request) error) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // standard header variables that should be set, for good measure. w.Header().Add("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate") w.Header().Add("X-Frame-Options", "DENY") w.Header().Add("X-Content-Type-Options", "nosniff") w.Header().Add("X-XSS-Protection", "1; mode=block") // serve the request err := f(w, r) if err == nil { return } // log the url for debugging purposes log.Println(r.Method, r.URL.Path) switch err.(type) { case badRequest: log.Println(err) http.Error(w, err.Error(), http.StatusBadRequest) case notFound: http.Error(w, "Not Found", http.StatusNotFound) case notAuthorized: http.Error(w, "Not Authorized", http.StatusUnauthorized) case notImplemented: http.Error(w, "Not Implemented", http.StatusForbidden) case forbidden: http.Error(w, "Forbidden", http.StatusForbidden) case internalServerError: http.Error(w, "Internal Server Error", http.StatusInternalServerError) default: log.Println(err) http.Error(w, "oops", http.StatusInternalServerError) } } }