From 2ddc013c84a048caf82f0787855d1b35c7ce82e3 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sun, 22 May 2022 12:19:25 +0200 Subject: [PATCH] Add panic recovery middleware --- cmd/boardvoting/handlers.go | 32 ++++++++++++++++---------------- cmd/boardvoting/middleware.go | 18 +++++++++++++++++- cmd/boardvoting/routes.go | 3 ++- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/cmd/boardvoting/handlers.go b/cmd/boardvoting/handlers.go index 9459e1d..45de331 100644 --- a/cmd/boardvoting/handlers.go +++ b/cmd/boardvoting/handlers.go @@ -71,7 +71,19 @@ func newTemplateCache() (map[string]*template.Template, error) { return cache, nil } -func (app *application) render(w http.ResponseWriter, status int, page string, data interface{}) { +type templateData struct { + Voter *models.Voter + Flashes []string + Params struct { + Flags struct { + Unvoted bool + } + } + PrevPage, NextPage string + Motions []*models.MotionForDisplay +} + +func (app *application) render(w http.ResponseWriter, status int, page string, data *templateData) { ts, ok := app.templateCache[page] if !ok { app.serverError(w, fmt.Errorf("the template %s does not exist", page)) @@ -93,19 +105,7 @@ func (app *application) render(w http.ResponseWriter, status int, page string, d _, _ = buf.WriteTo(w) } -type motionListTemplateData struct { - Voter *models.Voter - Flashes []string - Params struct { - Flags struct { - Unvoted bool - } - } - PrevPage, NextPage string - Motions []*models.MotionForDisplay -} - -func (m *motionListTemplateData) setPaginationParameters(first, last *time.Time) error { +func (m *templateData) setPaginationParameters(first, last *time.Time) error { motions := m.Motions if len(motions) > 0 && first.Before(motions[len(motions)-1].Proposed) { @@ -164,7 +164,7 @@ func (app *application) motionList(w http.ResponseWriter, r *http.Request) { return } - templateData := &motionListTemplateData{Motions: motions} + templateData := &templateData{Motions: motions} err = templateData.setPaginationParameters(first, last) if err != nil { @@ -173,7 +173,7 @@ func (app *application) motionList(w http.ResponseWriter, r *http.Request) { return } - app.render(w, http.StatusOK, "motions.html", &templateData) + app.render(w, http.StatusOK, "motions.html", templateData) } func calculateMotionListOptions(r *http.Request) (*models.MotionListOptions, error) { diff --git a/cmd/boardvoting/middleware.go b/cmd/boardvoting/middleware.go index 282f3f5..86303c8 100644 --- a/cmd/boardvoting/middleware.go +++ b/cmd/boardvoting/middleware.go @@ -17,7 +17,10 @@ limitations under the License. package main -import "net/http" +import ( + "fmt" + "net/http" +) func secureHeaders(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -39,3 +42,16 @@ func (app *application) logRequest(next http.Handler) http.Handler { next.ServeHTTP(w, r) }) } + +func (app *application) recoverPanic(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer func() { + if err := recover(); err != nil { + w.Header().Set("Connection", "close") + app.serverError(w, fmt.Errorf("%s", err)) + } + }() + + next.ServeHTTP(w, r) + }) +} diff --git a/cmd/boardvoting/routes.go b/cmd/boardvoting/routes.go index 42155dc..3fbabe5 100644 --- a/cmd/boardvoting/routes.go +++ b/cmd/boardvoting/routes.go @@ -39,10 +39,11 @@ func (app *application) routes() http.Handler { fileServer := statigz.FileServer(staticData, brotli.AddEncoding, statigz.EncodeOnInit) + mux.Handle("/favicon.ico", http.RedirectHandler("/static/images/favicon.ico", http.StatusMovedPermanently)) mux.Handle("/static/", http.StripPrefix("/static", fileServer)) mux.HandleFunc("/", app.home) mux.HandleFunc("/motions/", app.motionList) - return app.logRequest(secureHeaders(mux)) + return app.recoverPanic(app.logRequest(secureHeaders(mux))) }