Effectively using rescue_from

Norbert Crombach, 03 Nov 2007, 15:10 in ruby on rails, last updated 04 Nov 2007, 19:56 (edit).

Even though Ryan Daigle already covered it in his usual timely fashion, I’d like to share some real life examples of how we use the relatively new rescue_from functionality.

Because I usually prefer methods that raise exceptions instead of returning a boolean, like, say, save! instead of just save, I thought it would be nice if I could deal with some common exceptions on a higher level. This lead me to write a Rails patch based on the exception_handler plugin, which I previously used in some projects.

A few weeks later the patch found its way into Rails core, just in time for the 2.0 preview release. Now everybody can rewrite this:
class PostsController < ApplicationController
  def create
    @post = Post.create!(params[:post])
  rescue ActiveRecord::RecordInvalid
    render :action => :new
  end

  def update
    @post = Post.find(params[:id])
    @post.update_attributes!(params[:post])
  rescue ActiveRecord::RecordInvalid
    render :action => :edit
  end
end
to something like this:
class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordInvalid do |exception|
    render :action => (exception.record.new_record? ? :new : :edit)
  end
end

class PostsController < ApplicationController def create @post = Post.create!(params[:post]) end def update @post = Post.find(params[:id]) @post.update_attributes!(params[:post]) end end

And it just works.

Comments

  1. Remco about 24 hours later: (delete)

    The update action rendering an edit, in case of an exception, will not have @post properly set.

  2. Norbert Crombach 1 day later: (delete)

    Good catch.

  3. jare care 1 day later: (delete | show email)

    This example is terrible.

    First off remember this:

    "exceptions should not be expected"

    Your tendency of avoiding boolean methods like #save in favor of exception raising methods like #save! is conveying the message that invalid data is something you do NOT expect.

    That is wrong. Of course you expect invalid data, therefore that should NOT be handled using exceptions but instead using boolean methods and conditional logic.

    Your use of the ternary operator in your #rescue_from block is an example of DRYness going too far. The more "DRY" you try to keep that controller the more conditional logic you're going to have to add in your #rescue_from block. Thats going to get ugly real quick.

    For more info check out http://giantrobots.thoughtbot.com/2007/9/26/active-record-programming-with-exceptions

  4. Manfred Stienstra 2 days later: (delete)

    We've been having some discussion here at the office about how to properly structure a controller these last days. My (and Thijs') argument against this kind of logic is that it doesn't read like a story any more because you scatter the logic throughout the code. Remember GOSUB?

    Norbert has been working on a way to get something like this working without loosing readability.

  5. Bala Paranj 195 days later: (delete | show email)

    How will you set the flash message?

Add your comment

In order to fight spam on this blog, posting comments from a browser without javascript is currently not supported.