I blog about Ruby on Rails, coding, and servers

Dynamic Error Pages, Corrected

Reading time 3 minutes

Earlier today @alan_meier pointed out that in certain circumstances, my post on dynamic error pages leads to unexpected results: namely, though most errors are caught, 404s are not. I didn’t experience this myself because most 404s, for me, result in an ActiveRecord::RecordNotFound error, since my application has a wildcard route at the very end. But if you don’t then my post on dynamic error pages won’t work for you very well. Here, then, is an explanation of the problem and how to fix it.

Now in Rails 3, because routing is done as middleware (ActionDispatch), it seems that the ActionController::RoutingError that gets thrown by ActionDispatch no longer can be caught from ApplicationController – the error is already thrown and ActionDispatch renders /templates/rescues/routing_error.erb before the controller can rescue_from the error.

Essentially, rescue_from ActionController::RoutingError is never rescued because it’s raised in Rack, not the application itself.

Since we’re going to be exposing render_404 as an action, now, we have to make parameters into it optional: but we know that if render_exception doesn’t receive an exception, it actually got a 404.

Finally, we need to add a globbed, wildcard route at the conclusion of our routes.rb. But if we just add one in, then engines and Gems that also rely on wildcard routes will fail. The solution is to do this through our application.rb, like so:

Now it won’t punch any Gem or engine routes, but will still redirect 404s correctly to our render_404 action.

Thanks to @alan_meier for bringing this problem to my attention, and I hope this correction helps some people out!

Josh Symonds performs devops and server wrangling on cloud-scale infrastructures, deploys amazing web applications with Ruby on Rails, and creates awesome iOS apps with Objective-C and RubyMotion. He is founder and CTO of Symonds & Son, a development shop focused on quality and excellence.