bdunagan
fill the void

Posted
27 April 2012 @ 10am

Tagged
development

3 Comments

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

3 Comments

Posted by
Robert Reiz
1 May 2012 @ 8pm

Thanks for posting. I handled it similar.


Posted by
Darren
5 April 2013 @ 7pm

Thanks, this really helped me out.
I wanted to get an email whenever I had a 404 error and intercepting the RoutingError seemed impossible until I found this.

Thanks!


Posted by
Darren
5 April 2013 @ 7pm

I meant to add that; the rescue_from call will pass along any exception if you add a single parameter to the “render_not_found” method.

That way you get the actual RoutingError exception object to log or stick in an error email as I did. :-)


Leave a Comment