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