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