LoginSignup
2
0

More than 5 years have passed since last update.

Railsでルーティングエラーに処理を差し込む モンキーパッチ編

Posted at

環境

  • Ruby 2.4.1
  • Rails 5.1.4

みなさんこんにちは。

あいづちくんです。

例えば、Railsで開発をしていて、ルーティングエラー発生時に処理を差し込みたいという場面があったとします。

ルーティングエラーに処理を差し込む場合、モンキーパッチを当てることで対応できます。

今回の例では、ルーティングエラーのエラーの種類をFATALからWARNに変更しています。

ActionDispatchにモンキーパッチをあてて制御するパターンです。

以下の例ではconfig/initializers/logger.rbに追加しています。

unless Rails.env.development?
  class ActionDispatch::DebugExceptions
    alias_method :org_log_error, :log_error
    def log_error(request, wrapper)
      if wrapper.exception.is_a?  ActionController::RoutingError
        Rails.logger.warn wrapper.exception.message
      else
        org_log_error request, wrapper
      end
    end
  end
end_

ただ、モンキーパッチを当てたくない場合もあると思うので、そんなときには別の方法でも対応できます。

ちなみに、ActionDispatch::DebugExceptionsのlog_error周りはRails4とRails5で若干の違いがあったりするので、やはりモンキーパッチを当てるのは避けたほうが良いのかもしれません。

今回のパターンでは影響ありませんが、rails4系と5系ではlog_errorの引数が変わっており、バージョンによって影響が受けそうな印象を受けました。

Rails 4.2.10

ActionDispatch
    def log_error(env, wrapper)
      logger = logger(env)

      return unless logger
      exception = wrapper.exception
      trace = wrapper.application_trace
      trace = wrapper.framework_trace if trace.empty?

      ActiveSupport::Deprecation.silence do
        message = "\n#{exception.class} (#{exception.message}):\n"
        message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
        message << "  " << trace.join("\n  ")
        logger.fatal("#{message}\n\n")
      end
    end

Rails 5.1.4

ActionDispatch
      def log_error(request, wrapper)
        logger = logger(request)
        return unless logger
        exception = wrapper.exception
        trace = wrapper.application_trace
        trace = wrapper.framework_trace if trace.empty?

        ActiveSupport::Deprecation.silence do
          logger.fatal "  "
          logger.fatal "#{exception.class} (#{exception.message}):"
          log_array logger, exception.annoted_source_code if exception.respond_to?(:annoted_source_code)
          logger.fatal "  "
          log_array logger, trace
        end
      end

ということで、次回は別の方法をご紹介しようと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0