Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch Unknown action in Rails 3 for custom 404

I want to catch unknown action error in Rails 3, that shows "Unknown Action" error on development and the 404.html on production. I tried putting this rescue_from handler on my ApplicationController (and also on an actual controller, just in case) but I still see the ugly error.

I have custom stuff on the 404, and it can't be plain .html file.

My route:

match '/user/:id/:action', controller: 'users'

The URL I'm accessing: /user/elado/xxx

The rescue_from code:

rescue_from AbstractController::ActionNotFound, :with => :action_not_found

def action_not_found
  render text: "action_not_found"
end

The error in the browser:

Unknown action

The action 'xxx' could not be found for UsersController

And in the console:

Started GET "/user/elado/xxx" for 127.0.0.1 at 2011-09-07 19:16:27 -0700

AbstractController::ActionNotFound (The action 'xxx' could not be found for UsersController):

Tried also rescue_from ActionController::UnknownAction.

Any suggestions? Thanks!

like image 811
elado Avatar asked Sep 08 '11 03:09

elado


1 Answers

rescue_from was slightly broken when Rails 3 came out (still broken in 3.1 too). Basically you can't:

rescue_from ActionController::RoutingError

anymore. See here.

The solution, for now, is what hamiltop recommends. Use a catch all route that goes to your "routing error" route. Make sure you put it at the end of your config\routes.rb file so it is processed last.

# Any routes that aren't defined above here go to the 404
match "*a", :to => "application#routing_error"

def routing_error
    render "404", :status => 404
end

Note: This method has one major drawback. If you use an engine such as Jammit or Devise the catch all will route will make Rails ignore the engine's routes.

If you aren't using an engine that has it's own routes then you should be fine. However, if you do use an engine that defines its own routes see @arikfr's answer.

like image 81
Seth Jackson Avatar answered Oct 12 '22 13:10

Seth Jackson