Rails, Firefox, Anime, Mac – Still working on the blog theme!
In: General
10 Dec 2007I know I said I was going to try and keep the features in “a feature a day” to those not mentioned in popular places, but this feature is one of the few nicest features in Rails made by a contributor outside of the Rails core so I couldn’t resist mentioning it.
class CommentsController < ActionController::Base
rescue_from Comment::Spammy, :with => :moderate_comment
rescue_from ActiveRecord::RecordNotFound, :with => :redirect_if_not_found
protected
def moderate_comment
# Handle the exception, like placing the comment in a moderation queue
# and then rendering a different action.
end
def redirect_if_not_found
# Redirect somewhere...
end
end
Compare this to what you had to do with Rails 1.2.6 and earlier:
class CommentsController < ActionController::Base
def rescue_action_in_public(exception)
case exception
when Comment::Spammy
# Handle the exception as above.
when ActiveRecord::RecordNotFound
# Redirect somewhere...
else
super
end
end
end
Much clearer and reads almost like English. I don’t think I even need to explain what the code in the 1st example is trying to do.
Here’s another common use-case: dealing bad create/update actions. With rescue_from, you can simply do this:
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordInvalid do |exception|
render :action => (exception.record.new_record? ? :new : :edit)
end
end
No need for actions to be coded like this anymore!
def create
@comment = comment.create!(params[:comment])
rescue ActiveRecord::RecordInvalid
render :action => :new
end
This patch was committed in revision 7597 after a short discussion on the syntax and implementation over at the ticket. (More improvements on the implementation over at ticket #9645 for the interested.)
Norbert Crombach (Rails Trac username: norbert, WorkingWithRails profile) is another regular Rails contributor hailing from the Netherlands. The rescue_from is, in my opinion, one of his more significant contributions (and what a great one it is too).
While the new declarative rescue_from macro is useful, I’ve found myself liking the merb way of dealing with exceptions, where exception handling is delegated to an Exception controller. You can use layouts, templates, helpers and filters just like in ye plain olde controller. I’m still not so sure if it’s worth making a patch for Rails to emulate this behavior yet though!
Update: Rails 2.0 a feature a day #3 is now available Concatenate your stylesheets and JavaScripts in 3 seconds
8 Responses to Declarative exception-handling in your controllers – Rails 2.0 a feature a day #2
Martin
December 11th, 2007 at 7pm
Nice post!
One correction. Norbert has left Fingertips and is now doing consulting. ( I found out when I caught up with him at the local Ruby Users group in London last night).
links for 2007-12-12 « Bloggitation
December 12th, 2007 at 8am
[...] Declarative exception-handling in your controllers Rails 2.0 a feature a day #2 (tags: ruby rails programming) [...]
Interesting Rails Tidbits #1
December 12th, 2007 at 6pm
[...] Yeow demonstrates the very clean way in which you can handle controller-level exceptions in Rails [...]
john
December 12th, 2007 at 9pm
I too really like merbs error handling. Merbs gotta lot of potential!!
Infovore » links for 2007-12-18
December 19th, 2007 at 7am
[...] Declarative exception-handling in your controllers – Rails 2.0 a feature a day #2 – redemption in a … “…this feature is one of the few nicest features in Rails made by a contributor outside of the Rails core so I couldn’t resist mentioning it.” More on #rescue_from, with some nice use cases. (tags: rails rubyonrails ruby exceptionhandling exceptions) [...]
Xavier Noria
December 27th, 2007 at 5am
There was another patch before 2.0 was out that enhanced rescue_from in a few ways, see ticket #10079. (Disclaimer, I am the author.)
Tecker.LOG » ?????????????????Rails 2.0?? #2(??)
June 2nd, 2008 at 8pm
[...] ?????????????????Rails 2.0?? #2(??) ???Declarative exception-handling in your controllers – Rails 2.0 a feature a day #2 [...]
Enfranchised Mind » Functional (Meta)?Programming Stunts for Ruby and Groovy (and a Little Perl)
June 25th, 2008 at 2am
[...] Note that Rails 2.0 apparently jumped on this approach, too: here is a nice example. [...]