如何跳过在Rails中记录未捕获的异常?

时间:2018-09-23 09:59:39

标签: ruby-on-rails ruby-on-rails-5

使用自定义exceptions_apprescue_responses时,应用程序可以更好地控制未捕获的异常,并且DebugExceptions中间件的过多日志记录会变得很麻烦。

作为示例,应用程序知道如何处理ActionPolicy::Unauthorized,在exceptions_app中呈现正确的页面,因此以下日志是多余的:

FATAL -- :   
FATAL -- : ActionPolicy::Unauthorized (Not Authorized):
FATAL -- :   
FATAL -- : app/controllers/topics_suggest_controller.rb:47:in `topic_load' 

仅记录rescue_responses中列出的那些例外情况,最惯用的方法是什么?

1 个答案:

答案 0 :(得分:2)

方法1

很容易从应用程序的Rails堆栈中删除DebugExceptions中间件。

config/application.rb

config.middleware.delete ActionDispatch::DebugExceptions

问题在于,正是这种中间件决定了Rails无法找到路线并在这种情况下抛出ActionController::RoutingError。因此,如果您想对自己的exceptions_app中的该异常做出反应,那么这种方法对您来说是行不通的。

如果在找不到路由的情况下可以查看HTTP状态404和纯文本响应Not found,请继续使用此方法。

方法2

猴子补丁或以某种方式更改ActionDispatch::DebugExceptions。实际上,2013年有人提议更改DebugExceptions的行为,以便跳过rescue_responses9343中注册的日志记录异常,其中有示例代码。

我认为要覆盖整个类太多了,所以我选择覆盖负责记录错误的method log_error

lib/ext/suppress_exceptions.rb

module Ext
  module SuppressExceptions
    private

    def log_error(_request, wrapper)
      exception = wrapper.exception
      return if ActionDispatch::ExceptionWrapper.rescue_responses.key? exception.class.name
      super
    end
  end
end

config/initializers/error_handling.rb

require_dependency 'ext/suppress_exceptions'

ActiveSupport.on_load(:action_controller) do
  ActionDispatch::DebugExceptions.prepend Ext::SuppressExceptions
end