在Rails 3中捕获自定义404的未知操作

ela*_*ado 12 ruby-on-rails http-status-code-404 ruby-on-rails-3

我想在Rails 3中捕获未知的操作错误,该错误显示开发时的"未知操作"错误以及生产中的404.html.我尝试将此rescue_from处理程序放在我的ApplicationController上(以及实际的控制器,以防万一),但我仍然看到了丑陋的错误.

我在404上有自定义的东西,它不能是普通的.html文件.

我的路线:

match '/user/:id/:action', controller: 'users'
Run Code Online (Sandbox Code Playgroud)

我正在访问的URL: /user/elado/xxx

rescue_from代码:

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

def action_not_found
  render text: "action_not_found"
end
Run Code Online (Sandbox Code Playgroud)

浏览器中的错误:

Unknown action

The action 'xxx' could not be found for UsersController
Run Code Online (Sandbox Code Playgroud)

在控制台中:

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):
Run Code Online (Sandbox Code Playgroud)

也试过rescue_from ActionController::UnknownAction.

有什么建议?谢谢!

Set*_*son 14

当Rails 3出现时,rescue_from略有损坏(在3.1中仍然被打破).基本上你不能:

rescue_from ActionController::RoutingError
Run Code Online (Sandbox Code Playgroud)

了.看到这里.

目前,解决方案是hamiltop推荐的解决方案.使用捕获到"路由错误"路由的所有路由.确保将它放在config\routes.rb文件的末尾,以便最后处理它.

# 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
Run Code Online (Sandbox Code Playgroud)

注意:此方法有一个主要缺点.如果你使用像Jammit或Devise这样的引擎,那么所有路由都将使Rails忽略引擎的路由.

如果您没有使用拥有自己路线的引擎,那么您应该没问题.但是,如果您使用定义其自己路线的引擎,请参阅@ arikfr的答案.


ari*_*kfr 9

使用catch所有路径来处理404错误(正如@Seth Jackson建议的那样)有一个主要缺点:如果你使用定义自己路由的任何Rails引擎(例如Jammit),它们的路由将被忽略.

更好,更兼容的解决方案是使用可以捕获404错误的Rack中间件.在我的一个项目中,我实现了将这些错误报告给Hoptoad的Rack中间件.我的实现基于这个:https://github.com/vidibus/vidibus-routing_error,但我没有再次调用我的Rails应用程序来处理404错误,而是在Rack中间件中执行它并让nginx显示404页面.