Read more

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

Henning Koch
August 03, 2016Software engineer at makandra GmbH

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.

Illustration web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
Read more Show archive.org snapshot

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.

Posted by Henning Koch to makandra dev (2016-08-03 11:19)