In this article, I’ll explain how rails catches exceptions that may happen in your code, and how it renders a nice error page, depending on the Rails environment, and how you can customise it.

I won’t be talking about rescue_from, and ActionController::Rescue, but about the rack part.

Remember, it’s all Rack !

If you read my previous article about [Rails request handling](blog.siami.fr/diving-in-rails-the-request-handling), you know that Rails is based on Rack, and uses middlewares for various things.

Rails also handles exceptions with middlewares.

This article will explain how exceptions are handled in a production environment. If you are interested in understanding how Rails displays errors in development environment, have a look at the ActionDispatch::DebugExceptions middleware.

The role of this middleware is to find a file in the public directory to render the exception, and possibly to find a file in the correct locale.

For example, when issuing a 500 error, this middleware will display the file public/500.html

The call method will get the status from the path info, get the content type of the request thanks to ActionDispatch::Request and prepare a hash containing the status and a human readable message in case the request is in another format than HTML in order to render it instead of the HTML file.

Customisation

It’s possible to use a different app to render exceptions, by setting config.exceptions_app in application.rb or in an environment config file.

Some people want to render very specific errors and need an access to rails goodness when rendering those pages.

It’s possible to go meta and assign our own rack app (the rails app) as our exception handling app, so when an exception arises, the corresponding status code will be called right into our app :