cerrado @ v0.0.14

 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.ErrRepositoryNotFound) {
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}