7

Here is my code about a small demonstration webserver written with the Go language and the gorilla mux package :

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    fmt.Fprintf(w, "Hi there, I love %s!", vars["username"])
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        errorHandler(w, r, http.StatusNotFound)
        return
    }
    vars := mux.Vars(r)
    fmt.Fprintf(w, "Hi there, I love %s!", vars["username"])
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/help/{username}/", handler)
    http.Handle("/", r)
    http.ListenAndServe(":8080", nil)
}

But I don't find a way on how to implement a custom 404 page.

But I can't make a r.HandleFunc("/",...) but it will be too greedy.

Bussiere
  • 500
  • 13
  • 60
  • 119
  • 2
    For serving a custom error page yourself, see [httprouter configuring NotFound](http://stackoverflow.com/questions/30500322/httprouter-configuring-notfound/30500491#30500491). – icza Apr 25 '17 at 14:26

4 Answers4

13

The Router exports a NotFoundHandler field which you can set to your custom handler.

r := mux.NewRouter()
r.NotFoundHandler = MyCustom404Handler
mkopriva
  • 35,176
  • 4
  • 57
  • 71
11

Sometimes, you spend a lot of time building a stack of middleware that does many things like logging, sending metrics and so... And the default 404 handler just skips all the middlewares.

I was able to solve this issue by re-setting the default 404 handler like this:

router := mux.NewRouter()
router.Use(someMiddleware())
// Re-define the default NotFound handler
router.NotFoundHandler = router.NewRoute().HandlerFunc(http.NotFound).GetHandler()

Now, the 404 default handler is also going thru all the middlewares.

eexit
  • 138
  • 2
  • 8
  • Cool solution. But you have to do this assigning either after declaring your real routes or by using `BuildOnly()` method to prevent this route from acting like a wildcard. – Berkant İpek Aug 02 '19 at 10:09
  • Works, but You should define this NotFoundHandler registered once all the handlers are registered, otherwise, it will override all the handlers – sharath chandra Jul 14 '21 at 09:10
2

Set the NotFoundHandler to a handler method that returns your custom 404 page.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
2
r := mux.NewRouter()

h := http.HandlerFunc(NotFound)
r.NotFoundHandler = h
    
func NotFound(w http.ResponseWriter, r *http.Request) {
        
}
Faruk AK
  • 249
  • 2
  • 6