捕获所有类型的错误并在rails 4中呈现404页面

时间:2014-05-06 11:12:05

标签: ruby-on-rails ruby error-handling

我的代码在这里

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  #before_filter :session_must_exist
  protect_from_forgery with: :exception

  helper_method :current_user, :back_url, :parent_url
  unless Rails.application.config.consider_all_requests_local
    rescue_from Exception, :with => :method_missing
    rescue_from ActiveRecord::RecordNotFound, :with => :method_missing
    rescue_from AbstractController::ActionNotFound, :with => :method_missing
    rescue_from ActionController::RoutingError, :with => :method_missing
    rescue_from ActionController::UnknownController, :with => :method_missing
    rescue_from ActionController::UnknownAction, :with => :method_missing
  end

  def method_missing(m, *args, &block)
    Rails.logger.error(m)
    redirect_to :controller=>"errors", :action=>"error_404"
    render/redirect_to somewhere else
  end
end

但它不适合我。它给了我们

AbstractController::ActionNotFound (The action 'show' could not be found for BuildInstallersController):
  actionpack (4.0.0) lib/abstract_controller/base.rb:131:in `process'
  actionpack (4.0.0) lib/abstract_controller/rendering.rb:44:in `process'
  actionpack (4.0.0) lib/action_controller/metal.rb:195:in `dispatch'
  actionpack (4.0.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.0.0) lib/action_controller/metal.rb:231:in `block in action'
  actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `call'
  actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
  actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:48:in `call'
  actionpack (4.0.0) lib/action_dispatch/journey/router.rb:71:in `block in call'
  actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `each'
  actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `call'
  actionpack (4.0.0) lib/action_dispatch/routing/route_set.r

2 个答案:

答案 0 :(得分:0)

问题是rescue_from只是从控制器中发生的异常中解救而且AbstractController::ActionNotFound是一个路由问题,因此在实例化控制器之前会引发它。

你应该能够做到你需要的:

match '*a', :to => 'errors#error_404'

添加为路线的最后一行。

然而,最优雅的解决方案是使用如下的exception_apps:

# your environment file
config.exceptions_app = ->(env) { ErrorsController.action(:error_404).call(env) }

答案 1 :(得分:0)

您可以捕获所有的routes.rb文件,

  if Rails.env.production? # if you want to use it for production environment only
    %w{ 404 422 500 }.each do |err|
      get err, to: "errors#error_#{err}"
    end
  end