use builtin error interface for http handlers
5 files changed, 27 insertions(+), 19 deletions(-)
M domain/content/publisher/mux.go → domain/content/publisher/mux.go
@@ -31,7 +31,7 @@ ErrCannotDetermineUser = ihttp.NewError("cannot determine user", http.StatusInternalServerError) ErrRenderFailure = ihttp.NewError("failed to render page", http.StatusInternalServerError) ) -func (s *Service) Index(w http.ResponseWriter, r *http.Request) ihttp.Error { +func (s *Service) Index(w http.ResponseWriter, r *http.Request) error { userName := "Guest" isLoggedIn := false if user, err := getUserFromRequest(r); err == nil {@@ -62,7 +62,7 @@ // Login initiates the OIDC authentication flow with PKCE S256. // PKCE (Proof Key for Code Exchange) protects against authorization code interception attacks // by using a cryptographically random verifier and its SHA256 hash challenge. // See: https://www.rfc-editor.org/rfc/rfc7636 -func (s *Service) Login(w http.ResponseWriter, r *http.Request) ihttp.Error { +func (s *Service) Login(w http.ResponseWriter, r *http.Request) error { // Generate random state for CSRF protection state, err := generateRandomState() if err != nil {@@ -106,7 +106,7 @@ // Callback handles the OIDC provider's redirect after authentication. // It verifies the state parameter (CSRF protection), exchanges the authorization code // for tokens using the PKCE verifier, validates the ID token, and creates a session. -func (s *Service) Callback(w http.ResponseWriter, r *http.Request) ihttp.Error { +func (s *Service) Callback(w http.ResponseWriter, r *http.Request) error { ctx := r.Context() // Verify state parameter (CSRF protection)@@ -212,7 +212,7 @@ return nil } -func (s *Service) Logout(w http.ResponseWriter, r *http.Request) ihttp.Error { +func (s *Service) Logout(w http.ResponseWriter, r *http.Request) error { // Clear session cookie http.SetCookie(w, &http.Cookie{ Name: sessionCookieName,@@ -263,7 +263,7 @@ return base64.URLEncoding.EncodeToString(b), nil } -func (s *Service) Style(w http.ResponseWriter, r *http.Request) ihttp.Error { +func (s *Service) Style(w http.ResponseWriter, r *http.Request) error { w.Header().Set("Content-Type", "text/css") http.ServeFileFS(w, r, basetpl.Files, "style.css")
M domain/identity/webfinger/service.go → domain/identity/webfinger/service.go
@@ -59,7 +59,7 @@ func (s *Service) RegisterHandlers(mux *ihttp.ServeMux) { mux.HandleFunc("/.well-known/webfinger", s.HandleFunc) } -func (s *Service) HandleFunc(w http.ResponseWriter, r *http.Request) ihttp.Error { +func (s *Service) HandleFunc(w http.ResponseWriter, r *http.Request) error { resource := r.URL.Query().Get("resource") if resource == "" { return ErrMissingResourceParameter
M domain/web/mux.go → domain/web/mux.go
@@ -26,19 +26,23 @@ "Access-Control-Max-Age": "3600", } ) -func (website *Website) ErrorHandler(err ihttp.Error, w http.ResponseWriter, r *http.Request) { +func (website *Website) ErrorHandler(err error, w http.ResponseWriter, r *http.Request) { + hErr, ok := err.(ihttp.Error) + if !ok { + hErr = ihttp.NewError(err.Error(), http.StatusInternalServerError) + } if strings.Contains(r.Header.Get("Accept"), "text/html") { - w.WriteHeader(err.StatusCode()) - err := templates.Error(*website.siteSettings, err).Render(w) + w.WriteHeader(hErr.StatusCode()) + err := templates.Error(*website.siteSettings, hErr).Render(w) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } else { - http.Error(w, err.Error(), err.StatusCode()) + http.Error(w, hErr.Error(), hErr.StatusCode()) } } -func (website *Website) ServeHTTP(w http.ResponseWriter, r *http.Request) ihttp.Error { +func (website *Website) ServeHTTP(w http.ResponseWriter, r *http.Request) error { urlPath := r.URL.Path if r.URL.Query().Has("go-get") && r.URL.Query().Get("go-get") == "1" { urlPath = "/go" + r.URL.Path@@ -80,7 +84,7 @@ return nil } -func (website *Website) Calendar(w http.ResponseWriter, r *http.Request) ihttp.Error { +func (website *Website) Calendar(w http.ResponseWriter, r *http.Request) error { analytics.WithTitle(r, "Calendar") err := calendar.CalendarPage(*website.siteSettings, website.calendar).Render(w) if err != nil {@@ -98,7 +102,7 @@ re := regexp.MustCompile( "^(.*)\\." + strings.ReplaceAll(website.config.WildcardDomain, ".", `\.`) + "$", ) replace := "${1}." + website.config.Domains[0] - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) ihttp.Error { + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) error { switch { case r.URL.Query().Has("go-get") && r.URL.Query().Get("go-get") == "1": return website.ServeHTTP(w, r)
M domain/web/website.go → domain/web/website.go
@@ -189,7 +189,7 @@ website.publisher.RegisterHandlers(mux) } if opts.Development { - staticHandler := func(w http.ResponseWriter, r *http.Request) ihttp.Error { + staticHandler := func(w http.ResponseWriter, r *http.Request) error { http.ServeFileFS(w, r, templates.Files, r.URL.Path) return nil