97 lines
2 KiB
Go
97 lines
2 KiB
Go
package routes
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"foobar/views"
|
|
"net/http"
|
|
|
|
"github.com/a-h/templ"
|
|
)
|
|
|
|
type userError struct {
|
|
error
|
|
user string
|
|
}
|
|
|
|
type redirectURL string
|
|
|
|
type postRouteRedirectFunc func(http.ResponseWriter, *http.Request) (redirectURL, error)
|
|
|
|
type routeGetFunc func(http.ResponseWriter, *http.Request) (templ.Component, error)
|
|
|
|
var (
|
|
errUser = errors.New("user error")
|
|
)
|
|
|
|
func newUserError(msg string) *userError {
|
|
return &userError{
|
|
user: msg,
|
|
}
|
|
}
|
|
|
|
func (u *userError) Error() string {
|
|
return u.user
|
|
}
|
|
|
|
func (u redirectURL) Valid() bool {
|
|
return len(u) > 0 && u[0] == '/'
|
|
}
|
|
|
|
func getRouteMiddleware(fun routeGetFunc) http.HandlerFunc {
|
|
// TODO: handle boosted HTMX requests gracefully
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
component, err := fun(w, r)
|
|
if err != nil {
|
|
logInternalError(w, err)
|
|
return
|
|
}
|
|
err = component.Render(context.Background(), w)
|
|
if err != nil {
|
|
logInternalError(w, err)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func redirectHtmxFormMiddleware(fun postRouteRedirectFunc) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
hxRequest := r.Header.Get("HX-Request") == "true"
|
|
|
|
redirectURL, err := fun(w, r)
|
|
if err != nil {
|
|
w.Header().Add("HX-Retarget", "#error-target")
|
|
w.Header().Add("HX-Reswap", "innerHTML")
|
|
w.WriteHeader(http.StatusUnprocessableEntity)
|
|
if u, ok := err.(*userError); ok {
|
|
if hxRequest {
|
|
err = views.ErrorBox(u.user).Render(context.Background(), w)
|
|
if err != nil {
|
|
logError(fmt.Errorf("%w: %s", err, r.URL.Path))
|
|
}
|
|
} else {
|
|
_, _ = w.Write([]byte(u.user))
|
|
|
|
}
|
|
return
|
|
} else {
|
|
msg := "Internal error... See the server logs for more information"
|
|
_ = views.ErrorBox(msg).Render(context.Background(), w)
|
|
logError(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
if !redirectURL.Valid() {
|
|
panic("not implemented")
|
|
}
|
|
|
|
if hxRequest {
|
|
w.Header().Add("HX-Redirect", string(redirectURL))
|
|
} else {
|
|
http.Redirect(w, r, string(redirectURL), http.StatusFound)
|
|
}
|
|
}
|
|
}
|