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

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

環境

  • 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::DebugExceptions#log_error

    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::DebugExceptions#log_error

      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

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

TAG

  • このエントリーをはてなブックマークに追加
金子 将範
エンジニア 金子 将範 rubyist

新しいことや難しい課題に挑戦することにやりがいを感じ、安定やぬるい事は退屈だと感じます。 考えるより先に手が動く、肉体派エンジニアで座右の銘は諸行無常。 大事なのは感性、プログラミングにおいても感覚で理解し、感覚で書きます。