Basic Exception notification in Rails 3

There are a number of services out there, like Airbrake, that will capture exceptions from a Rails app and do clever stuff with them. They let you manage your exceptions and track any work that results from them. But they all cost money, and might be overkill for what you are doing. So here is a quick guide to making your Rails application email you when exceptions happen, and how to display better error pages to your users.
I’m assuming that you already have email delivery configured. If you don’t, then get that sorted first, and make sure it works.

Setting up message delivery

Now configure Exception Notification in your environments. You probably only want to use it in your production environment, but you may want to test it in your development environments. So in config/environments/production.rb put something like this (season to taste)…

The rescue_from method tells Rails what to do when certain exceptions are raised and make it all the way to the top of the controller call stack without getting caught. In this case we tell it to call one of two controller methods, render_error (for errors) and render_not_found (for all the various ways you can not find something).

You’ll need to define the two methods in a protected block in application_controller.rb

Create some templates for displaying a nice error message to your users, and place them in app/views/errors and the layout errors.html.erb (assuming you are using ERB). You can make these as nice as you like. These will be rendered by the two methods.

In addition, render_error will also send you an email using ExceptionNotifier and the configuration we set up earlier.

If you wanted to you could also send alerts from render_not_found. This could be useful for notifying you of broken links, but is also likely to generate a lot of crap as search engines, crawlers and malware try to load certain pages speculatively.

Caveat for Rails 3

If you are using Rails 2 everything should be working fine now. If you are using Rails 3 then we have one more step to get it working right.

As of Rails 3 errors in routing, for example if you try to access a URL that has no route associated with it, are no longer handled by ApplicationController, they are dealt with by the middleware. If you want to handle them in the same way as all your other errors then we have to do a bit more work.

At the very bottom of config/routes.rb, add something like the following:

This will route all unmatched routes to my HomeController'srouting_error action. You could put this action anywhere you like. You could create a controller specifically for handling errors like this, or put it in whatever controller handles your root (which is what I’ve done).