「ActiveRecord::RecordNotFoundをraiseしたときに404になるときに静的な404ページ出しているのでそれをそのまま真似て他のエラーでもキャッチしてくれないかな」という悩みを持つ人向け
検証したバージョン
$ bin/rails -v Rails 7.0.6
前提としての動きのメカニズム
- ActionDispatch::ExceptionWrapper.rescue_responsesにExceptionと対応するエラーのシンボルがある
- Rack::Utils.status_codeを使ってシンボルを数値に変換
- 変換した値を使って
/public/{{ステータスコード数値}}.html
あるいは/public/{{ステータスコード数値}}.{{i18nのロケール文字列}}.html
の静的ファイルを読み取り表示。
詳しい挙動をトレースしたものは以下の記事に順を追って説明されているので参照のこと。
独自のエラーでも表示をしてもらうには
たとえば以下のようなエラークラスを作って、このエラーをキャッチした場合は404を出したいとする。
module OriginalException class HyperAccident < StandardError end end
その場合は環境ごとのconfigに当該エラーをキャッチした場合の設定を追記してあげる。
Rails.application.configure do ### 中略 ### config.action_dispatch.rescue_responses = { # keyは対象となるException、valueに設定するのはHTTPステータスコードのシンボル。 "OriginalException::HyperAccident" => :not_found } end
上記のように記載してあげれば、404と同じ静的なHTMLを表示してくれる。例えば以下の場合 /test/0
でアクセスするとpublic配下に配置した404.htmlを表示する
class TestController < ApplicationController def show raise ::OriginalException::HyperAccident if params[:id] == "0" render json: {test: params} end end
独自のviewや処理を加えたい場合は rescue_from
を活用したほうがいいがそちらは関連リンク参照のこと。