// RecoverPanics wraps an http Handler to recover and log panics. func RecoverPanics(handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { defer func() { if x := recover(); x != nil { http.Error(w, "apis panic. Look in log for details.", http.StatusInternalServerError) glog.Errorf("APIServer panic'd on %v %v: %v\n%s\n", req.Method, req.RequestURI, x, debug.Stack()) } }() defer httplog.NewLogged(req, &w).StacktraceWhen( httplog.StatusIsNot( http.StatusOK, http.StatusCreated, http.StatusAccepted, http.StatusBadRequest, http.StatusMovedPermanently, http.StatusTemporaryRedirect, http.StatusConflict, http.StatusNotFound, http.StatusUnauthorized, http.StatusForbidden, errors.StatusUnprocessableEntity, http.StatusSwitchingProtocols, ), ).Log() // Dispatch to the internal handler handler.ServeHTTP(w, req) }) }
func tooManyRequests(req *http.Request, w http.ResponseWriter) { // "Too Many Requests" response is returned before logger is setup for the request. // So we need to explicitly log it here. defer httplog.NewLogged(req, &w).Log() // Return a 429 status indicating "Too Many Requests" w.Header().Set("Retry-After", RetryAfter) http.Error(w, "Too many requests, please try again later.", errors.StatusTooManyRequests) }