Go and Gorilla Mux NotFoundHandler not working
Asked Answered
A

2

17

I just can't get this NotFoundHandler to work. I'd like to serve a static file on every get request, given that it exists, otherwise serve index.html. Here's my simplified router at the moment:

func fooHandler() http.Handler {
  fn := func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Foo"))
  }
  return http.HandlerFunc(fn)
}

func notFound(w http.ResponseWriter, r *http.Request) {
  http.ServeFile(w, r, "public/index.html")
}

func main() {
  router = mux.NewRouter()
  fs := http.FileServer(http.Dir("public"))

  router.Handle("/foo", fooHandler())
  router.PathPrefix("/").Handler(fs)
  router.NotFoundHandler = http.HandlerFunc(notFound)

  http.ListenAndServe(":3000", router)
}

/foo works ok

/file-that-exists works ok

/file-that-doesnt-exist doesn't work - I get 404 page not found instead of index.html

So what am I doing wrong here?

Abelmosk answered 26/10, 2014 at 13:16 Comment(0)
T
39

The problem is that router.PathPrefix("/").Handler(fs) will match every route and the NotFoundHandler is never executed. The NotFoundHandler is only executed when the router can't find a matching route.

When you explicitly define your routes it works as expected.

You could do something like:

router.Handle("/foo", fooHandler())
router.PathPrefix("/assets").Handler(fs)
router.HandleFunc("/", index)
router.HandleFunc("/about", about)
router.HandleFunc("/contact", contact)
router.NotFoundHandler = http.HandlerFunc(notFound)
Talanian answered 26/10, 2014 at 13:30 Comment(1)
What if the request is not landing to any handler and we are getting bad request in response ? is there anyway to test that scenario ?Microelement
T
5

This has worked for me

r.NotFoundHandler = http.HandlerFunc(NotFound)

Makesure your 'NotFound' function has:

func NotFound(w http.ResponseWriter, r *http.Request) { // a * before http.Request
Tumid answered 17/3, 2018 at 19:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.