Preparing for Rails 2.0: Controller-based exception handling

By Myles Eftos

Since Ruby is a pure Object-Oriented Language, exceptions play a big role in the flow of control. Previously, you had the choice of rescuing exceptions at a local level or you could override the rescue_action method in your controller.

The former method gave you really fine-grained control of what to do in the case of an exception:

rescue ActiveRecord::RecordInvalid
    render :action => 'new'

In this case, if the ActiveRecord::RecordInvalid exception is raised (the save! method will raise this if validation fails) Rails will render the ‘new’ action. It became clear, though that adding begin/rescues around the same methods is pretty time consuming and not very DRY – which is where the rescue_action became helpful:

def rescue_action(exception)
  if exception == ActionView::TemplateError
    render :template => 'errors/404'

This (rather contrived) example will trap any ActionView::TemplateError and render the 404.erb file in the /app/views/errors directory. You are able to drop that method into any controller (including app_controller), but again, there is a lot of work involved in setting them up, making sure each controller performs the correct action for a given exception, which is why Rails 2.0 introduces rescue_from.

rescue_from is an attribute of each controller, and allows you to define a method to run when a particular exception is called. So the above example would become:

rescue_from ActionView::TemplateError, :with => :render_404

def render_404(exception)
   render :template => 'errors/404'

or if you prefer to use a inline block:

rescue_from ActionView::TemplateError do { render :template => 'errors/404' }

In the current PR release, the rescue_from technique can only catch exceptions of an exact type, so it wouldn’t catch sub-classed exceptions – if you had a custom exception called MyTemplateError that extends ActionView::TemplateError the above code won’t work. The good news is a patch to edge rails fixes this issue, so the release version of Rails 2.0 will work as expected.

Meet the author
Myles a Perth-based web developer who has worked in all the major web languages, his weapon of choice being Ruby on Rails—although he’s found himself doing more and more front-end development in JavaScript, HTML, and CSS.


Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Front-end, once a week, for free.