前回に引き続き、better_errors gemによって想定とは違う挙動をしていた体験をしたので、記事にしました。
↓参考: 前回の記事
↓better_errors
背景: Rails7.1から例外のデフォルトログレベルがWARNになった
先日、とあるWebアプリのRailsアップグレード(Rails7.1→Rails8.0)をしていました。
config.load_defaultsが古かったので、Railsに合わせて引き上げる作業をしていたのですが、Rails7.1からconfig.action_dispatch.debug_exception_log_levelのデフォルトの値が従来の:fatalから:warnに変更されました。
この設定が変更されたPRを確認すると、「Ruby LoggerのドキュメントではFATALは『プログラムのクラッシュを引き起こす、処理不能なエラー』と定義されており、DebugExceptionがエラーを処理している現状と合わない。」という旨の説明がされています。
設定値変えてもログに変化がない?
そこで、この設定の値を :warnにして、ローカル環境で例外を発生させてみたのですが、ログには FATALとして表示されました。
ちなみに、ログレベルはseverityを使って表示できます。
config/environments/development.rb(簡略化しています。)
config.action_dispatch.debug_exception_log_level = :warn config.log_formatter = proc do |severity, time, progname, msg| "[#{time.strftime('%Y-%m-%d %H:%M:%S')}] #{severity} -- #{progname}: #{msg}\n" end
出力されるログのサンプル
[2025-09-14 23:17:44] FATAL -- : RuntimeError - 例外が発生: app/controllers/...
あれ?ここがWARNになるってことではないの、、?
better_errorsがログレベルを制御していた
アプリ内のコードを確認しても、特別ログレベルをカスタムしている場所はなかったので、Gemfileを確認すると、better_errorsがあり、怪しそうに思ったので試しにbetter_errorsをコメントアウトしてみました。
すると、、、
[2025-09-14 23:45:39] WARN -- : RuntimeError (例外が発生):
WARNになりました!
具体的には、以下の箇所で制御されていました。
better_errors/lib/better_errors/middleware.rb
def log_exception return unless BetterErrors.logger message = "\n#{@error_page.exception_type} - #{@error_page.exception_message}:\n" message += backtrace_frames.map { |frame| " #{frame}\n" }.join BetterErrors.logger.fatal message # ←ここ end
実際にここをwarnに変えたらログはWARNで表示されました。
さいごに
コントリビュートチャンス?と思いましたが、better_errorsは2年前を最後にコミットが追加されておらず、メンテが止まっているようです。
内容が軽微なこともあり、モンキーパッチを当てるなどはせず、「config.load_defaultsに合わせてデフォルト値は変わるが、ローカル環境のログ上はFATALのまま」、というのを許容することにしました。
better_errosの良い代替gemってあるのかなー、、とぼんやり思ったりしています。