cerrado @ b4204817527de481bbba5b547ef6d797600be130

 1package ext
 2
 3import (
 4	"errors"
 5	"fmt"
 6	"log/slog"
 7	"net/http"
 8
 9	"git.gabrielgio.me/cerrado/pkg/service"
10	"git.gabrielgio.me/cerrado/templates"
11)
12
13type (
14	Router struct {
15		middlewares []Middleware
16		router      *http.ServeMux
17	}
18	Middleware          func(next http.HandlerFunc) http.HandlerFunc
19	ErrorRequestHandler func(w http.ResponseWriter, r *http.Request) error
20)
21
22func NewRouter() *Router {
23	return &Router{
24		router: http.NewServeMux(),
25	}
26}
27
28func (r *Router) Handler() http.Handler {
29	return r.router
30}
31
32func (r *Router) AddMiddleware(middleware Middleware) {
33	r.middlewares = append(r.middlewares, middleware)
34}
35
36func wrapError(next ErrorRequestHandler) http.HandlerFunc {
37	return func(w http.ResponseWriter, r *http.Request) {
38		if err := next(w, r); err != nil {
39			if errors.Is(err, service.ErrRepositoryNotFound) {
40				NotFound(w, r)
41			} else {
42				slog.Error("Internal Server Error", "error", err)
43				InternalServerError(r, w, err)
44			}
45		}
46	}
47}
48
49func (r *Router) run(next ErrorRequestHandler) http.HandlerFunc {
50	return func(w http.ResponseWriter, re *http.Request) {
51		req := wrapError(next)
52		for _, r := range r.middlewares {
53			req = r(req)
54		}
55		req(w, re)
56	}
57}
58
59func (r *Router) HandleFunc(path string, handler ErrorRequestHandler) {
60	r.router.HandleFunc(path, r.run(handler))
61}
62
63func NotFound(w http.ResponseWriter, r *http.Request) {
64	w.WriteHeader(http.StatusNotFound)
65	templates.WritePageTemplate(w, &templates.ErrorPage{
66		Message: "Not Found",
67	}, r.Context())
68}
69
70func Redirect(w http.ResponseWriter, location string) {
71	w.Header().Add("location", location)
72	w.WriteHeader(http.StatusTemporaryRedirect)
73}
74
75func InternalServerError(r *http.Request, w http.ResponseWriter, err error) {
76	w.WriteHeader(http.StatusInternalServerError)
77	templates.WritePageTemplate(w, &templates.ErrorPage{
78		Message: fmt.Sprintf("Internal Server Error:\n%s", err.Error()),
79	}, r.Context())
80}