Skip to content

Commit 9e99612

Browse files
committed
moving HTTPHandler to http_handler
1 parent 5ae41f0 commit 9e99612

File tree

2 files changed

+87
-76
lines changed

2 files changed

+87
-76
lines changed

http_handler.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package veun
2+
3+
import (
4+
"context"
5+
"log/slog"
6+
"net/http"
7+
)
8+
9+
// HTTPHandler constructs an http.HTTPHandler given the RequestRenderable.
10+
func HTTPHandler(r RequestRenderable, opts ...HandlerOption) http.Handler {
11+
h := handler{Renderable: r}
12+
for _, opt := range opts {
13+
opt(&h)
14+
}
15+
return h
16+
}
17+
18+
// HTTPHandler constructs an http.HTTPHandler given the RequestRenderableFunc.
19+
func HTTPHandlerFunc(r RequestRenderableFunc, opts ...HandlerOption) http.Handler {
20+
h := handler{Renderable: r}
21+
for _, opt := range opts {
22+
opt(&h)
23+
}
24+
return h
25+
}
26+
27+
// HandlerOption is an option that can be provided to the handler.
28+
type HandlerOption func(h *handler)
29+
30+
// WithErrorHandler creates a HandlerOption that can be provided to HTTPHandler
31+
// or HTTPHandlerFunc.
32+
//
33+
// This can change the default error handling behavior of the handler.
34+
func WithErrorHandler(eh ErrorRenderable) HandlerOption {
35+
return func(h *handler) {
36+
h.ErrorHandler = eh
37+
}
38+
}
39+
40+
// WithErrorHandlerFunc is the same as WithErrorHandler.
41+
func WithErrorHandlerFunc(eh ErrorRenderableFunc) HandlerOption {
42+
return WithErrorHandler(eh)
43+
}
44+
45+
// handler implements http.Handler for a RequestRenderable.
46+
type handler struct {
47+
Renderable RequestRenderable
48+
ErrorHandler ErrorRenderable
49+
}
50+
51+
// ServeHTTP implements http.Handler.
52+
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
53+
renderable, next, err := h.Renderable.RequestRenderable(r)
54+
if err != nil {
55+
h.handleError(r.Context(), w, err)
56+
return
57+
}
58+
59+
html, err := Render(r.Context(), renderable)
60+
if err != nil {
61+
h.handleError(r.Context(), w, err)
62+
return
63+
}
64+
65+
if next != nil {
66+
next.ServeHTTP(w, r)
67+
}
68+
69+
_, err = w.Write([]byte(html))
70+
if err != nil {
71+
panic(err)
72+
}
73+
}
74+
75+
func (h handler) handleError(ctx context.Context, w http.ResponseWriter, err error) {
76+
html, rErr := handleRenderError(ctx, err, h.ErrorHandler)
77+
if rErr == nil && len(html) > 0 {
78+
w.WriteHeader(http.StatusInternalServerError)
79+
_, _ = w.Write([]byte(html))
80+
return
81+
}
82+
83+
// TODO: grab the logger from the context
84+
slog.Error("handler failed", "err", err)
85+
code := http.StatusInternalServerError
86+
http.Error(w, http.StatusText(code), code)
87+
}

http_request_renderable.go

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package veun
22

33
import (
4-
"context"
5-
"log/slog"
64
"net/http"
75
)
86

@@ -21,77 +19,3 @@ type RequestRenderableFunc func(*http.Request) (AsRenderable, http.Handler, erro
2119
func (f RequestRenderableFunc) RequestRenderable(r *http.Request) (AsRenderable, http.Handler, error) {
2220
return f(r)
2321
}
24-
25-
func HTTPHandlerFunc(r RequestRenderableFunc, opts ...HandlerOption) http.Handler {
26-
h := handler{Renderable: r}
27-
for _, opt := range opts {
28-
opt(&h)
29-
}
30-
return h
31-
}
32-
33-
func HTTPHandler(r RequestRenderable, opts ...HandlerOption) http.Handler {
34-
h := handler{Renderable: r}
35-
for _, opt := range opts {
36-
opt(&h)
37-
}
38-
return h
39-
}
40-
41-
type HandlerOption func(h *handler)
42-
43-
func WithErrorHandler(eh ErrorRenderable) HandlerOption {
44-
return func(h *handler) {
45-
h.ErrorHandler = eh
46-
}
47-
}
48-
49-
func WithErrorHandlerFunc(eh ErrorRenderableFunc) HandlerOption {
50-
return func(h *handler) {
51-
h.ErrorHandler = eh
52-
}
53-
}
54-
55-
// handler implements http.Handler for a RequestRenderable.
56-
type handler struct {
57-
Renderable RequestRenderable
58-
ErrorHandler ErrorRenderable
59-
}
60-
61-
// ServeHTTP implements http.Handler.
62-
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
63-
renderable, next, err := h.Renderable.RequestRenderable(r)
64-
if err != nil {
65-
h.handleError(r.Context(), w, err)
66-
return
67-
}
68-
69-
html, err := Render(r.Context(), renderable)
70-
if err != nil {
71-
h.handleError(r.Context(), w, err)
72-
return
73-
}
74-
75-
if next != nil {
76-
next.ServeHTTP(w, r)
77-
}
78-
79-
_, err = w.Write([]byte(html))
80-
if err != nil {
81-
panic(err)
82-
}
83-
}
84-
85-
func (h handler) handleError(ctx context.Context, w http.ResponseWriter, err error) {
86-
html, rErr := handleRenderError(ctx, err, h.ErrorHandler)
87-
if rErr == nil && len(html) > 0 {
88-
w.WriteHeader(http.StatusInternalServerError)
89-
_, _ = w.Write([]byte(html))
90-
return
91-
}
92-
93-
// TODO: grab the logger from the context
94-
slog.Error("handler failed", "err", err)
95-
code := http.StatusInternalServerError
96-
http.Error(w, http.StatusText(code), code)
97-
}

0 commit comments

Comments
 (0)