package main import "net/http" // handlerFunc ist die Handler-Signatur dieser App: wie http.HandlerFunc, aber // mit Fehler-Rückgabe. Der Gewinn ist nicht nur Kürze -- die alte Form // (writeError(...); return) machte ein vergessenes return zu einem stillen Bug: // der Handler lief weiter und schrieb eine zweite Antwort in denselben // ResponseWriter. Mit "return err" kann das strukturell nicht mehr passieren. type handlerFunc func(http.ResponseWriter, *http.Request) error // api hängt einen fehlerliefernden Handler in chi ein. Der Fehler geht durch // failRequest und wird damit in dem Format ausgegeben, das der Client erwartet // -- diese Endpunkte bedienen inzwischen beide Seiten (siehe wantsJSON). // // Das Gegenstück ist page(): dort ist die Antwort immer HTML, weil es sich um // Seiten und nicht um Endpunkte handelt. func api(h handlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if err := h(w, r); err != nil { failRequest(w, r, err) } } } // guard ist dasselbe für Middlewares: der Prüfschritt liefert einen Fehler, // statt selbst zu schreiben. Der ResponseWriter wird durchgereicht, weil // manche Prüfungen vor der Antwort noch Header setzen müssen. func guard(check func(http.ResponseWriter, *http.Request) error) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if err := check(w, r); err != nil { failRequest(w, r, err) return } next.ServeHTTP(w, r) }) } }