📝

Railsでエラーが起こったときの表示制御

1 min read

なに?

エラーが起こったとき、どういう処理がされるのかを追ってみた

ばーじょん

  • Ruby ruby 2.7.2p137
  • Rails 6.1.2

ながれ

以下の3段構えでエラーをキャッチするようになっている。

  1. ActionController::Rescueでチェック
  2. ActionDispatch::DebugExceptionsでチェック
  3. ActionDispatch::ShowExceptionsでチェック

ActionController::Rescue

rescue_fromで設定されたエラークラスかをチェックし、該当した場合は定義された処理を行う。

ActionDispatch::DebugExceptions

以下の設定の場合に、詳細なエラー画面を表示する。

config.consider_all_requests_local = true
# 以下はデフォルトtrueなので明示的には設定していないかもしれない
config.action_dispatch.show_exceptions = true

初期設定のdevelopmentモードはこうなっている。

このとき、以下のような詳細なエラー画面が表示される。
画面下部にはweb-consoleが起動しており、ちょっとしたデバッグも可能だ。

ActionDispatch::ShowExceptions

設定により簡素なエラー表示と汎用エラー表示の2種類がある。

簡素なエラー表示

# consider_all_requests_localの設定には左右されない
# config.consider_all_requests_local = true
config.action_dispatch.show_exceptions = false

おそらくこの状態で使う人はいないと思われる。

このとき、以下のようなエラーメッセージとバックトレースだけの簡素なエラー画面が表示される。

汎用エラー表示

config.consider_all_requests_local = false
# 以下はデフォルトtrueなので明示的には設定していないかもしれない
config.action_dispatch.show_exceptions = true

初期設定のproductionモードはこうなっている。

このとき、config.exceptions_appに沿ったエラー表示を行う。
デフォルトでは、#{Rails.root}/public/#{HTTPステータスコード}.htmlを表示する。
#{Rails.root}/public/#{HTTPステータスコード}.#{I18n.locale}.htmlがある場合は、そちらが優先される。
※ファイルがない場合は、bodyが空のレスポンスが404レスポンスが返る。

デフォルトの404.htmlはこちらだ。

余談

yuki24さんが作ったrambulanceというgemがある。
エラー表示用のキーと対応するviewを用意し、それらとエラークラスをマッピングすることにより、柔軟にエラーを表示するための仕組みを提供している。

このgemは、config.exceptions_appをカスタムして実現している。