How Rails chooses error pages (404, 500, ...) for exceptions

Updated . Posted . Visible to the public. Repeats.

When your controller action raises an unhandled exception, Rails will look at the exception's class and choose an appropriate HTTP status code and error page for the response.

For instance, an ActiveRecord::RecordNotFound will cause Rails to render a red "The page you were looking for doesn't exist" with a status code of "404" (not found).

The mapping from exception classes to error types is a hash in Rails.configuration.action_dispatch.rescue_responses. The default settings are:

{ "ActiveRecord::RecordNotFound"   => :not_found, 
  "ActiveRecord::StaleObjectError" => :conflict,
  "ActiveRecord::RecordInvalid"    => :unprocessable_entity,
  "ActiveRecord::RecordNotSaved"   => :unprocessable_entity }

Important

The keys are strings, not Class objects.

If an exception has no mapping, Rails will assume a status code of 500 (internal server error) and will render a red "We're sorry, but something went wrong"

Changing the mapping

You might want to change this mapping. In particular, you might want to map your own error classes to "404 not found". This will result in a more helpful error message than "Something has gone wrong". Also Google will stop crawling a 404 error, while it will retry 500 errors indefinitely.

To change the mapping, add this to your config/application.rb:

config.action_dispatch.rescue_responses.merge!(
  'MyClass::FileNotFound' => :not_found
)

Exception Notifier

Note that modifying the error mapping will not rescue that specific error – it's only changing the error page the user sees on that error.

If you consider an exception to mean "not found", you probably also want to ignore this exception in your exception notification (e.g. Exception Notifier Show archive.org snapshot ).

Testing error pages in development

You won't see error pages in development unless you set config.consider_all_requests_local = false in your config/development.rb. Without this setting, a stack trace will be shown instead.

Rescuing exceptions for specific exception types

If you want to rescue other exceptions than preconfigured in Rails.configuration.action_dispatch.rescue_responses, see this card.

Changing the layout for your exception page

If you want to change the layout for your error pages, see this card.

Henning Koch
Last edit
Felix Eschey
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2016-08-03 09:19)