winterwhisper
4/10/2012 - 9:03 AM

Rails 3 rescue_from routing error, variation on solution from http://techoctave.com/c7/posts/36-rails-3-0-rescue-from-routing-error-solution

Rails 3 rescue_from routing error, variation on solution from http://techoctave.com/c7/posts/36-rails-3-0-rescue-from-routing-error-solution

#make this your last route.
match '*unmatched_route', :to => 'application#raise_not_found!'
class ApplicationController < ActionController::Base

  ...
  #Problem:
  #In rails 3.0.1+ it is no longer possible to do this anymore;
  #  rescue_from ActionController::RoutingError, :with => :render_not_found
  #
  #The ActionController::RoutingError thrown is not caught by rescue_from.
  #The alternative is to to set a catch-all route to catch all unmatched routes and send them to a method which renders an error
  #As in http://techoctave.com/c7/posts/36-rails-3-0-rescue-from-routing-error-solution
  #A slight variation on this is to add the route and method, but have the method raise an ActionController::RoutingError
  #This way you can keep the usage of rescue_from and treat all error handling in the same way. 

  #continue to use rescue_from in the same way as before
  unless Rails.application.config.consider_all_requests_local
    rescue_from Exception, :with => :render_error
    rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found   
    rescue_from ActionController::RoutingError, :with => :render_not_found
  end 

  #called by last route matching unmatched routes.  Raises RoutingError which will be rescued from in the same way as other exceptions.
  def raise_not_found!
    raise ActionController::RoutingError.new("No route matches #{params[:unmatched_route]}")
  end

  #render 500 error 
  def render_error(e)
    respond_to do |f| 
      f.html{ render :template => "errors/500", :status => 500 }
      f.js{ render :partial => "errors/ajax_500", :status => 500 }
    end
  end
  
  #render 404 error 
  def render_not_found(e)
    respond_to do |f| 
      f.html{ render :template => "errors/404", :status => 404 }
      f.js{ render :partial => "errors/ajax_404", :status => 404 }
    end
  end

  ...

end