Improve this page

Error Handling

An error is Go way to tell something went wrong. In this chapter, you'll learn how to return errors from a route handler and how Buffalo will catch any non-handled error.

Returning Errors From a Handler

func MyHandler(c buffalo.Context) error {
  // Return any old error, this will result in a 500 status code.
  return errors.New("boom!")
}
func MyHandler(c buffalo.Context) error {
  // Use the Error function on the context.
  // This will result in a status code of 401.
  return c.Error(401, errors.New("Unauthorized!"))
}

Default Error Handling (Development)

In "development" mode (GO_ENV=development), Buffalo will generate some helpful errors pages for you.

An example of a `500` error in development mode.

If you use a JSON or a XML content type, the error is returned in the proper type:

{
  "error": "could not find test/",
  "trace": "could not find test/\ngithub.com/gobuffalo/gobuffalo/vendor/github.com/gobuffalo/buffalo.(*App).fileServer.func1\n\t/home/michalakst/go/src/github.com/gobuffalo/gobuffalo/vendor/github.com/gobuffalo/buffalo/route_mappings.go:97\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:1947\nnet/http.StripPrefix.func1\n\t/usr/local/go/src/net/http/server.go:1986\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:1947\ngithub.com/gobuffalo/gobuffalo/vendor/github.com/gorilla/mux.(*Router).ServeHTTP\n\t/home/michalakst/go/src/github.com/gobuffalo/gobuffalo/vendor/github.com/gorilla/mux/mux.go:162\ngithub.com/gobuffalo/gobuffalo/vendor/github.com/markbates/refresh/refresh/web.ErrorChecker.func1\n\t/home/michalakst/go/src/github.com/gobuffalo/gobuffalo/vendor/github.com/markbates/refresh/refresh/web/web.go:23\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:1947\ngithub.com/gobuffalo/gobuffalo/vendor/github.com/gobuffalo/buffalo.(*App).ServeHTTP\n\t/home/michalakst/go/src/github.com/gobuffalo/gobuffalo/vendor/github.com/gobuffalo/buffalo/server.go:127\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2694\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:1830\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:2361",
  "code": 404
}
<response code="404">
  <error>could not find test/</error>
  <trace>could not find test/
github.com/gobuffalo/gobuffalo/vendor/github.com/gobuffalo/buffalo.(*App).fileServer.func1
	/home/michalakst/go/src/github.com/gobuffalo/gobuffalo/vendor/github.com/gobuffalo/buffalo/route_mappings.go:97
net/http.HandlerFunc.ServeHTTP
	/usr/local/go/src/net/http/server.go:1947
net/http.StripPrefix.func1
	/usr/local/go/src/net/http/server.go:1986
net/http.HandlerFunc.ServeHTTP
	/usr/local/go/src/net/http/server.go:1947
github.com/gobuffalo/gobuffalo/vendor/github.com/gorilla/mux.(*Router).ServeHTTP
	/home/michalakst/go/src/github.com/gobuffalo/gobuffalo/vendor/github.com/gorilla/mux/mux.go:162
github.com/gobuffalo/gobuffalo/vendor/github.com/markbates/refresh/refresh/web.ErrorChecker.func1
	/home/michalakst/go/src/github.com/gobuffalo/gobuffalo/vendor/github.com/markbates/refresh/refresh/web/web.go:23
net/http.HandlerFunc.ServeHTTP
	/usr/local/go/src/net/http/server.go:1947
github.com/gobuffalo/gobuffalo/vendor/github.com/gobuffalo/buffalo.(*App).ServeHTTP
	/home/michalakst/go/src/github.com/gobuffalo/gobuffalo/vendor/github.com/gobuffalo/buffalo/server.go:127
net/http.serverHandler.ServeHTTP
	/usr/local/go/src/net/http/server.go:2694
net/http.(*conn).serve
	/usr/local/go/src/net/http/server.go:1830
runtime.goexit
	/usr/local/go/src/runtime/asm_amd64.s:2361</trace>
</response>

In "production" mode (GO_ENV=production), Buffalo will not generate pages that have developer style information. Instead the pages are simpler.

Custom Error Handling

While Buffalo will handle errors for you out of the box, it can be useful to handle errors in a custom way. To accomplish this, Buffalo allows for the mapping of HTTP status codes to specific handlers. This means the error can be dealt with in a custom fashion.

app = buffalo.New(buffalo.Options{
  Env: ENV,
})

app.ErrorHandlers[422] = func(status int, err error, c buffalo.Context) error {
  res := c.Response()
  res.WriteHeader(422)
  res.Write([]byte(fmt.Sprintf("Oops!! There was an error %s", err.Error())))
  return nil
}

app.GET("/oops", MyHandler)

func MyHandler(c buffalo.Context) error {
  return c.Error(422, errors.New("Oh no!"))
}
GET /oops -> [422] Oh no!

In the above example any error from your application that returns a status of 422 will be caught by the custom handler and will be dealt with accordingly.