Skip to content

Instantly share code, notes, and snippets.

@Sujimichi
Created April 10, 2012 09:03
Show Gist options
  • Star 43 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save Sujimichi/2349565 to your computer and use it in GitHub Desktop.
Save Sujimichi/2349565 to your computer and use it in GitHub Desktop.
Rails 3 rescue_from routing error, variation on solution from http://techoctave.com/c7/posts/36-rails-3-0-rescue-from-routing-error-solution
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
#make this your last route.
match '*unmatched_route', :to => 'application#raise_not_found!'
@andriesfilmer
Copy link

Thanks. This was usefull for me ;)

Only Rails 4 needs a different syntax in the routes.rb. It does not accept Match anymore.

get '*unmatched_route', :to => 'application#raise_not_found!'

@moeffju
Copy link

moeffju commented Mar 12, 2015

@andriesfilmer That will only match on GET requests, you will want to use:

match '*unmatched_route', :to => 'application#raise_not_found!', :via => :all

@mtkp
Copy link

mtkp commented Oct 16, 2015

Consider adding the following if you use Strong Parameters and #require, otherwise you'll return 500s on bad requests.

rescue_from ActionController::ParameterMissing, with: :render_bad_request

...

def render_bad_request(e)
  # render ..., :status => 400
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment