package admin import ( "encoding/json" "log/slog" "net/http" ) // renderHTMXError sends an error response suitable for htmx. For htmx // requests it sets HX-Trigger so the client fires a toast; the global // htmx:responseError listener in main.js is the fallback for non-triggering // handlers. For plain browsers it degrades to http.Error. serverErr is // logged but never exposed — pass userMsg for anything user-visible. func renderHTMXError(w http.ResponseWriter, r *http.Request, status int, userMsg string, serverErr error) { if serverErr != nil { slog.Error("admin htmx handler error", "path", r.URL.Path, "status", status, "err", serverErr, ) } if userMsg == "" { userMsg = http.StatusText(status) } if r.Header.Get("HX-Request") == "true" { trigger := map[string]map[string]string{ "toast": {"message": userMsg, "type": "error"}, } if b, err := json.Marshal(trigger); err == nil { w.Header().Set("HX-Trigger", string(b)) } w.Header().Set("HX-Reswap", "none") w.WriteHeader(status) return } http.Error(w, userMsg, status) }