go-chi / go-chi/chi

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

Open
#910 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
22.8k
Forks
1.2k
Avg merge
5h 17m
Merged PRs (30d)
10

Description

Hi, I have the following code:

```go
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

```sh
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`

2. http://localhost:8091/v1/bad-books-url/45345

```sh
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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.