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:
begin
user.save!
rescue ActiveRecord::RecordInvalid
render :action => 'new'
end
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' else super end end
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'
end
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.
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.