Rails 7からRails 7.1へ移行するとaction_dispatch.show_exceptions
という設定項目に関連して「DEPRECATION WARNING
」が表示されることがあります。これは、この設定項目にRails 7.1で変更があったためです。この記事では、この変更の背景や対応方法についてご説明します。
とりあえず急いで対処する方法
詳細はさておき、Rails 7.1においてaction_dispatch.show_exceptions
関連の警告やエラーを消したいという方は、以下のステップをお試し下さい。
ステップ1
config/environments/test.rb
のconfig.action_dispatch.show_exceptions
を:rescuable
に設定します。bin/rails test
を実行して、エラーが出なければそれでOKです。エラーが出てしまった場合はステップ2に進みます。
ステップ2
config.action_dispatch.show_exceptions
の設定値を、元々true
としていた場合には:all
、false
としていた場合には:none
へと設定し直します。この設定により以前と同じ挙動になります。bin/rails test
を実行して問題がないことを確認します。
警告が発生しうる状況
Rails 7からRails 7.1へ移行(アップデート、アップグレード)し、bin/rails test
を実行すると以下の警告が表示される場合があります。
DEPRECATION WARNING: Setting action_dispatch.show_exceptions to false is deprecated. Set to :none instead.
これはRuby on Rails 7.1 リリースノートにある通り「config.action_dispatch.show_exceptions
にtrue
やfalse
を設定することを非推奨化」という更新がRails 7.1であったためです。なお、この更新の詳細や対応方法についての公式な情報は対応するpull request (#45867)で確認できます。
Pull request #45867の概要
ポイントはテスト(test)環境を本番(production)環境に近づけつつ、想定外のエラーが発生した場合には詳細情報が得られるようにしたいというところにあります。この目的を達成するために新たに導入されたのが:rescuable
であり、この:rescuable
が今後デフォルトとなります。
対応方法
まずはRailsガイドの手順に従い、その手順の中にあるbin/rails app:update
コマンドの実行も行います。
次に、config/environments/test.rb
のconfig.action_dispatch.show_exceptions
を今後のデフォルトとなる:rescuable
にしてbin/rails test
でテストを実行します。テストの実行に問題が無く、
の仕様で支障が無い場合はこれでOKです。:rescuable
設定で
を選択してテストを実行するとエラーが出るようになってしまうケースとして考えられるのは、テスト内の:rescuable
assert_raises
において引数で指定した例外をキャッチできなくなりテスト失敗となるケースです。
では、本番環境が意図的に救出(rescue)しエラーページ(例えば「404 not foundページ」)を表示するいくつかの例外は、テスト環境でも例外のまま上がってはこなくなり、救出されてエラーページのレスポンスが返るようになります。:rescuable
そこで、
に合わせてテストを書き換える場合は、救出される例外を:rescuable
assert_raises
する記述を消し、代わりに、適切な(つまり本番環境と同じ)エラーレスポンスが返ってくることを確認するassert_response
の記述を加えると良いでしょう(assert_response
の日本語版Railsガイドの説明はこちら)。具体例を以下に示します。
変更前の例:
test "something" do
assert_raises(ActionController::RoutingError) do
get something_path( @something )
end
end
変更後の例:
test "something" do
get something_path( @something )
assert_response :missing
end
なお、こういったテストの変更をしたくない場合には、config.action_dispatch.show_exceptions
を、元々true
と設定していた場合には:all
、false
と設定していた場合には:none
へと設定し直します。この設定により以前と同じ挙動になり、変更なしでテストがこれまでのように通るはずです。
参考情報:pull request #45867の機械翻訳
本件のpull request (#45867)の主要部分を機械翻訳で日本語にしたものを以下に示します。
背景
統合テスト中、アプリケーションが本番環境とできるだけ近い反応を示すことが望ましいです。これにより、アプリケーションの振る舞いが適切に行われているという自信が得られます。
Railsのテストでは、テスト環境と本番環境との間に一つ大きな不一致があります。それは、HTTPリクエスト中に発生した例外(例えばActiveRecord::RecordNotFound)がテスト内で再度発生し、救出されて404レスポンスに変換されるのではなく、再度発生するということです。
config.action_dispatch.show_exceptionsをtrueに設定すると、テスト環境は本番環境のように動作しますが、予期しない内部サーバーエラーが発生した場合、テストは有用なスタックトレースを提示するのではなく、不透明な500レスポンスになってしまいます。これにより、デバッグがより困難になります。
これにより、開発者は高品質な統合テストと失敗時の改善されたデバッグ体験の間で選択を迫られます。
私は、両方を達成できると提案します。
解決策
設定オプションのconfig.action_dispatch.show_exceptionsを、ブール値から3つの値、:all、:rescuable、:noneのいずれかに変更します。:allと:noneの値は、それぞれ以前のtrueとfalseと同じように動作します。以前はtrueだったもの(現在は:all)は、非テスト環境では引き続きデフォルトとなります。
新たに追加された:rescuableの値は、テスト環境の新しいデフォルトとなります。これは、ActionDispatch::ExceptionWrapper.rescue_responsesで定義された救出可能な例外に対してのみ、レスポンス内で例外を表示します。予期しない内部サーバーエラーが発生した場合、エラーの原因となった例外はテスト内で引き続き発生し、有用なスタックトレースと良好なデバッグ体験を提供します。
Rails 7からRails 7.1へ移行に関するその他のTips
Rails 7からRails 7.1へ移行(アップデート、アップグレード)に関する情報は、本件のものも、本件以外のものも含めて、TechTipsの以下のトピックでまとめられていますので、是非ご覧下さい。