scribble

fill the void - bdunagan

27 Apr 2012
rescue_from RoutingError in Rails 3

Rails 3.0 handles routing errors (ActionController::RoutingError) differently than Rails 2.3. The middleware addition means the error is passed to ActionDispatch, instead of ApplicationController. A bit ago, I actually removed the catch-all route at the bottom of routes.rb because I thought the ApplicationController::rescue_from handled any routing errors. Not true. Rails 3.2 doesn't resolved it either.

There is an open GitHub issue for it: "Can no longer rescue_from ActionController::RoutingError". (In fact, it's old enough to be an issue migrated from Lighthouse.) There are several solutions posted inline in the issue's comments. José Valim from the Rails core team suggests simply adding the catch-all route back to routes.rb; others suggest overriding ActionDispatch::ShowExceptions::render_exception. All seem focused on rendering the 404 page manually. However, I wanted to make rescue_from work. My solution is the catch-all route and raising the exception manually.

# routes.rb

# Any other routes are handled here (as ActionDispatch prevents RoutingError from hitting ApplicationController::rescue_action).
match "*path", :to => "application#routing_error"
# application_controller.rb

rescue_from ActionController::RoutingError, :with => :render_not_found

def routing_error
  raise ActionController::RoutingError.new(params[:path])
end

def render_not_found
  render :template => "misc/404"
end
Previous LinkedIn Twitter GitHub Email Next