rescue_from ActionController :: RoutingError不起作用

Bog*_*iel 11 ruby-on-rails ruby-on-rails-4

我正试图拯救ActionController::RoutingError,我无法让它发挥作用.我尝试了几乎所有我能在网上找到的东西,包括Rails 4中的rescue_from ActionController :: RoutingError.我有错误控制器和错误页面.我开始工作康康舞access deniedRecordNotFound,但我可以解决RoutingError.

对于康康舞我在里面使用它 application_controller.rb

rescue_from CanCan::AccessDenied do
    render template: 'errors/error_403', status: 403
  end
Run Code Online (Sandbox Code Playgroud)

我的路线中有这个:

match "/404", to: "errors#error_404", via: :all
Run Code Online (Sandbox Code Playgroud)

如果我做同样的事情RoutingError它将无法正常工作.

我也试过,match '*path', :to => "errors#error_404"但我得到了错误.

我怎么解决这个问题?

编辑:如果我RoutingError对拒绝访问做同样的事情:

    rescue_from ActionController::RoutingError do
       render template: 'errors/error_404', status: 404
    end
Run Code Online (Sandbox Code Playgroud)

它不会起作用.

max*_*max 33

ActionController::RoutingError当Rails的尝试匹配的路由请求被提出.这种情况发生在Rails甚至初始化控制器之前 - 因此您的ApplicationController永远不会有机会挽救异常.

相反,Rails默认exceptions_app启动 - 请注意,这是一个Rack意义上的应用程序 - 它需要带有请求的ENV哈希并返回响应 - 在这种情况下是静态/public/404.html文件.

您可以做的是让您的Rails应用程序处理动态呈现错误页面:

# config/application.rb
config.exceptions_app = self.routes # a Rack Application

# config/routes.rb
match "/404", :to => "errors#not_found", :via => :all
match "/500", :to => "errors#internal_server_error", :via => :all
Run Code Online (Sandbox Code Playgroud)

然后,您将设置一个特定的控制器来处理错误页面 - 不要在ApplicationController类中执行此操作,因为您将向所有控制器添加一个not_foundinternal_server_error方法!

class ErrorsController < ActionController::Base
  protect_from_forgery with: :null_session

  def not_found
    render(status: 404)
  end

  def internal_server_error
    render(status: 500)
  end
end
Run Code Online (Sandbox Code Playgroud)

Matt Brictson借来的代码:动态Rails错误页面 - 阅读完整纲要.

  • 我的错。我需要通过在config / environment / development.rb中添加这一行config.consider_all_requests_local = false来告诉Rails渲染错误页面。现在一切正常。 (6认同)

B S*_*ven 10

有一个更好的方法来做到这一点:

路由文件

Rails.application.routes.draw do
  match '*unmatched', to: 'application#route_not_found', via: :all
end
Run Code Online (Sandbox Code Playgroud)

应用控制器.rb

class ApplicationController < ActionController::Base
  def route_not_found
    render file: Rails.public_path.join('404.html'), status: :not_found, layout: false
  end
end
Run Code Online (Sandbox Code Playgroud)

要在本地进行测试,请设置以下内容并重新启动服务器。

配置/开发.rb

config.consider_all_requests_local = false
Run Code Online (Sandbox Code Playgroud)

用 Rails 6 测试。