feat: global error handler with template rendering
Some checks are pending
Cadoles/bouncer/pipeline/pr-develop Build started...
Some checks are pending
Cadoles/bouncer/pipeline/pr-develop Build started...
This commit is contained in:
@ -1,9 +1,11 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -23,7 +25,6 @@ import (
|
||||
"forge.cadoles.com/cadoles/bouncer/internal/store"
|
||||
|
||||
"github.com/Masterminds/sprig/v3"
|
||||
"github.com/getsentry/sentry-go"
|
||||
sentryhttp "github.com/getsentry/sentry-go/http"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
@ -112,6 +113,7 @@ func (s *Server) run(parentCtx context.Context, addrs chan net.Addr, errs chan e
|
||||
s.directorCacheTTL,
|
||||
),
|
||||
),
|
||||
director.WithHandleErrorFunc(s.handleError),
|
||||
)
|
||||
|
||||
if s.serverConfig.HTTP.UseRealIP {
|
||||
@ -217,27 +219,24 @@ func (s *Server) createReverseProxy(ctx context.Context, target *url.URL) *httpu
|
||||
httpTransport.DialContext = dialer.DialContext
|
||||
|
||||
reverseProxy.Transport = httpTransport
|
||||
reverseProxy.ErrorHandler = s.handleError
|
||||
reverseProxy.ErrorHandler = s.handleProxyError
|
||||
|
||||
return reverseProxy
|
||||
}
|
||||
|
||||
func (s *Server) handleDefault(w http.ResponseWriter, r *http.Request) {
|
||||
err := errors.Errorf("no proxy target found")
|
||||
|
||||
logger.Error(r.Context(), "proxy error", logger.CapturedE(err))
|
||||
sentry.CaptureException(err)
|
||||
|
||||
s.renderErrorPage(w, r, err, http.StatusBadGateway, http.StatusText(http.StatusBadGateway))
|
||||
s.handleError(w, r, http.StatusBadGateway, errors.Errorf("no proxy target found"))
|
||||
}
|
||||
|
||||
func (s *Server) handleError(w http.ResponseWriter, r *http.Request, err error) {
|
||||
func (s *Server) handleError(w http.ResponseWriter, r *http.Request, status int, err error) {
|
||||
err = errors.WithStack(err)
|
||||
logger.Error(r.Context(), err.Error(), logger.CapturedE(err))
|
||||
|
||||
logger.Error(r.Context(), "proxy error", logger.CapturedE(err))
|
||||
sentry.CaptureException(err)
|
||||
s.renderErrorPage(w, r, err, status, http.StatusText(status))
|
||||
}
|
||||
|
||||
s.renderErrorPage(w, r, err, http.StatusBadGateway, http.StatusText(http.StatusBadGateway))
|
||||
func (s *Server) handleProxyError(w http.ResponseWriter, r *http.Request, err error) {
|
||||
s.handleError(w, r, http.StatusBadGateway, err)
|
||||
}
|
||||
|
||||
func (s *Server) renderErrorPage(w http.ResponseWriter, r *http.Request, err error, statusCode int, status string) {
|
||||
@ -288,12 +287,18 @@ func (s *Server) renderPage(w http.ResponseWriter, r *http.Request, page string,
|
||||
return
|
||||
}
|
||||
|
||||
if err := blockTmpl.Execute(w, templateData); err != nil {
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := blockTmpl.Execute(&buf, templateData); err != nil {
|
||||
logger.Error(ctx, "could not render proxy page", logger.CapturedE(errors.WithStack(err)))
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := io.Copy(w, &buf); err != nil {
|
||||
logger.Error(ctx, "could not write page", logger.CapturedE(errors.WithStack(err)))
|
||||
}
|
||||
}
|
||||
|
||||
func NewServer(funcs ...OptionFunc) *Server {
|
||||
|
Reference in New Issue
Block a user