Using rescue_from in Rails controllers

I deal with a lot of old Rails code, and one of the things that has been bugging me recently is the use of rescue_action_in_public. It’s not incredibly flexible if you want to actually handle specific exceptions in a given controller in order to redirect the user.

An update to this strategy involves the use of rescue_from. You can achieve something akin to the Twitter API error messages using something like the strategy below, in addition to making all of these handlers easy to override in your controllers. I’d like to wrap up a more complete and polished version of the code below into a gem, but until then this post will have to do.

class ApplicationController < ActionController::Base
  rescue_from ActionController::RoutingError, :with => :route_not_found
  rescue_from ActionController::UnknownAction, :with => :unknown_action
  rescue_from ActionController::MethodNotAllowed, :with => :method_not_allowed
  if (defined? ActiveRecord)
    rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
  end

  def route_not_found(exception)
    handle_error('no route', :status => :not_found)
  end

  def unknown_action(exception)
    handle_error('unknown action', :status => :not_found)
  end

  def method_not_allowed(exception)
    handle_error('method not allowed', :status => :not_found)
  end

  def record_not_found(exception)
    handle_error('no record', :status => :not_found)
  end

  def handle_error(message, params)
    error = {
      :error => message,
      :request => request.request_method.to_s.upcase! + ' ' + request.request_uri
    }
    status = params[:status] || :not_found

    respond_to do |format|
      format.xml  { render :xml  => error.to_xml, :status => status }
      format.json { render :json => error.to_json, :status => status }
      format.yaml { render :text => error.to_yaml, :status => status }
    end
  end
end
Advertisements
This entry was posted in Exception Handling and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s