Railsで例外をHTTPステータスコードにマッピングする方法
Railsアプリケーションで例外(エラー)が発生したときに、どのHTTPステータスコードを返すかを指定する方法を順を追って説明します。
はじめに
Railsで例外をHTTPステータスコードにマッピングする方法は複数あります:
- ApplicationControllerでrescue_fromを使う方法
- カスタム例外ハンドラーを作成する方法
- config/application.rbで設定する方法
- ActionDispatch::ExceptionWrapper.rescue_responsesを使う方法
それぞれにメリット・デメリットがありますが、今回紹介する ActionDispatch::ExceptionWrapper.rescue_responses
を使った方法が最もシンプルで実装しやすいと思います。アプリケーション全体で一括設定でき、コードもわずか数行で済みます。
🔹 全体像
ActiveSupport.on_load(:action_controller) do
ActionDispatch::ExceptionWrapper.rescue_responses.merge!(
"ActiveHash::RecordNotFound" => :not_found,
"Pagy::OverflowError" => :not_found
)
end
このコードの目的は、特定の例外が発生した際に HTTP ステータスコード 404(:not_found)を返すように Rails に指示することです。
各要素の意味
✅ ActiveSupport.on_load(:action_controller)
これは Railsのフック です。
- ActionController(Railsのコントローラー機能)が読み込まれたときに、ブロック内の処理を実行します
- gemなどで定義する際に便利なパターンで、本体よりも後に読み込まれるようなモジュールでも、このブロック内で処理を追記できます
✅ ActionDispatch::ExceptionWrapper.rescue_responses
これは、例外クラス名とHTTPステータスコードのマッピングです。
- たとえば
"ActiveRecord::RecordNotFound"
が発生すると、通常は 404(Not Found)を返します
✅ merge!
この Hash に新しい例外マッピングを追加しています。
今回は下記の2つを追加しています:
"ActiveHash::RecordNotFound" => :not_found
"Pagy::OverflowError" => :not_found
各エラーの意味
🔸 ActiveHash::RecordNotFound
- ActiveHash は、DBを使わずにモデルのように扱えるGem
- 存在しないIDなどを検索したときにこのエラーが発生します
- これを 404 として扱うことで、一般的な「見つかりません」扱いになります
🔸 Pagy::OverflowError
- Pagy は軽量なページネーションGem
- ページ番号が存在しない(例:最大5ページなのに
?page=10
)とこの例外が発生 - これも「そのページは存在しない」という意味で 404 にするのが自然です
✅ なぜ必要か
Rails標準ではこれらのエラーは 500 Internal Server Error 扱いになる可能性があります。でも実際はクライアント側のミス(存在しないIDやページ指定)なので、404 Not Found として返す方が適切。
📁 実際の実装場所
このコードは、Railsアプリケーションの イニシャライザー に配置します:
config/initializers/exception_mapping.rb
このファイルを作成し、上記のコードを記述することで、アプリケーション起動時に例外マッピングが設定されます。
🔚 まとめ
例外クラス | 返すステータス | 意味 |
---|---|---|
ActiveHash::RecordNotFound | :not_found | 指定されたIDのレコードが無い |
Pagy::OverflowError | :not_found | 存在しないページを指定した |
Railsが自動的にこのマッピングを見て、エラーハンドリングしてくれるようになります。これでユーザーにとっても自然な挙動になります。
終わりに
そもそもエラーページは、通常のユーザーが目にするものではありません。ですので、無理にカスタマイズしたり、特別にレイアウトを指定したりする必要はないと考えています。
もちろん、URLに応じてレコメンドコンテンツを表示したり、上部にランディングページを表示したりといったニーズもあるかもしれませんが、まずはRailsの標準仕様に従って、シンプルに構築するのがおすすめです。
Discussion