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.








November 11th, 2007 at 3:15 pm
The Rails team have just released Release Candidate 1, which fixes rescue_from.
You can pull the latest version from the repository by a:
svn co http://svn.rubyonrails.org/rails/tags/rel_2-0-0_RC1 rails
November 13th, 2007 at 6:28 am
Nice one, thanks madpilot ;)