mugit/internal/handlers/util.go(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
package handlers
import (
"fmt"
"log/slog"
"net/http"
"time"
)
func (h *handlers) templ(w http.ResponseWriter, name string, data any) {
if err := h.t.ExecuteTemplate(w, name, data); err != nil {
w.WriteHeader(http.StatusInternalServerError)
slog.Error("template", "name", name, "err", err)
}
}
func (h *handlers) write404(w http.ResponseWriter, err error) {
slog.Info("404", "err", err)
w.WriteHeader(http.StatusNotFound)
h.templ(w, "404", nil)
}
func (h *handlers) write500(w http.ResponseWriter, err error) {
slog.Info("500", "err", err)
w.WriteHeader(http.StatusInternalServerError)
h.templ(w, "500", nil)
}
func (h *handlers) recoverMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
h.write500(w, fmt.Errorf("panic: %v", err))
}
}()
next.ServeHTTP(w, r)
})
}
func (h *handlers) loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
wrapped := wrapResponseWriter(w)
next.ServeHTTP(wrapped, r)
slog.Info("http request",
"method", r.Method,
"status", wrapped.status,
"path", r.URL.Path,
"latency", time.Since(start).String(),
"ua", r.UserAgent(),
)
})
}
type responseWriter struct {
http.ResponseWriter
status int
wroteHeader bool
}
func wrapResponseWriter(w http.ResponseWriter) *responseWriter {
return &responseWriter{ResponseWriter: w}
}
func (rw *responseWriter) Status() int {
return rw.status
}
func (rw *responseWriter) WriteHeader(code int) {
if rw.wroteHeader {
return
}
rw.status = code
rw.ResponseWriter.WriteHeader(code)
rw.wroteHeader = true
}
|