go-chi/chi

When registering a custom Middleware and a custom NotFoundHandler, both are executed when a 404 URL is loaded

Edenshaw opened this issue · 1 comments

Hi, I have the following code:

func main() {
	router := getRouter()
	setRoutes(router)

	server := &http.Server{
		Addr:         ":8091",
		Handler:      router,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 2 * time.Minute,
	}
	err := server.ListenAndServe()
	if err != nil {
		fmt.Printf("Error starting server: %s\n", err)
	}
}

func setRoutes(router *chi.Mux) {
	router.Route("/v1", func(r chi.Router) {
		r.Get("/books/{id}", printBookInfoHandler)
	})
}

func getRouter() *chi.Mux {
	router := chi.NewRouter()
	router.Use(getSimpleMiddleware)
	router.NotFound(getNotFoundHandler)
	return router
}

func getSimpleMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, _ = fmt.Fprintf(w, "Hello! ")
		w.WriteHeader(http.StatusOK)
		next.ServeHTTP(w, r)
	})
}

func getNotFoundHandler(w http.ResponseWriter, r *http.Request) {
	_, _ = fmt.Fprintf(w, "Not Found!")
	w.WriteHeader(http.StatusNotFound)
}

func printBookInfoHandler(w http.ResponseWriter, r *http.Request) {
	bookId := chi.URLParam(r, "id")
	currentTime := fmt.Sprint("Current date and time: ", time.Now().Format("Mon Jan 2 15:04:05.999999999 MST 2006"))
	_, err := fmt.Fprintf(w, "You have requested the book with Id: %s\n%s", bookId, currentTime)
	if err != nil {
		panic("Could not write a response")
	}
}

When I start the server and go to the following URLs I see a strange behaviour:

  1. http://localhost:8091/v1/books/45345
Hello! You have requested the book with Id: 453452345
Current date and time: Tue Apr 16 17:50:18.841064 -05 2024

So far, all good. Both handlers were executed: getSimpleMiddleware and printBookInfoHandler

  1. http://localhost:8091/v1/bad-books-url/45345
Hello! Not Found!

Why? I am expecting for ONLY the NotFoundHandler to kick in, but it is executing the entire chain of middlewares.

Is there an option in the router that I am missing? Is this the expected behaviour?

My config:
chi v5 (v5.0.12)
go 1.22.2
MBP M1 Apple

I believe it's because middlewares are executed before the handler.