go

Showing custom 404 error page with standard http package


Assuming that we have:

http.HandleFunc("/smth", smthPage)
http.HandleFunc("/", homePage)

User sees a plain "404 page not found" when they try a wrong URL. How can I return a custom page for that case?

Update concerning gorilla/mux

Accepted answer is ok for those using pure net/http package.

If you use gorilla/mux you should use something like this:

func main() {
    r := mux.NewRouter()
    r.NotFoundHandler = http.HandlerFunc(notFound)
}

And implement func notFound(w http.ResponseWriter, r *http.Request) as you want.


Solution

  • I usually do this:

    package main
    
    import (
        "fmt"
        "net/http"
    )
    
    func main() {
        http.HandleFunc("/", homeHandler)
        http.HandleFunc("/smth/", smthHandler)
        http.ListenAndServe(":12345", nil)
    }
    
    func homeHandler(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path != "/" {
            errorHandler(w, r, http.StatusNotFound)
            return
        }
        fmt.Fprint(w, "welcome home")
    }
    
    func smthHandler(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path != "/smth/" {
            errorHandler(w, r, http.StatusNotFound)
            return
        }
        fmt.Fprint(w, "welcome smth")
    }
    
    func errorHandler(w http.ResponseWriter, r *http.Request, status int) {
        w.WriteHeader(status)
        if status == http.StatusNotFound {
            fmt.Fprint(w, "custom 404")
        }
    }
    

    Here I've simplified the code to only show custom 404, but I actually do more with this setup: I handle all the HTTP errors with errorHandler, in which I log useful information and send email to myself.