#はじめに
読者対象はプログラミング初学者とします。
googleで「エラーハンドリング routes」と検索しても、良いページが見つからなかったので書きました。
#注意
エラーハンドリングはコピペで済まさず、熟考した上で実装してください。
エラー処理の考え方について、この伊藤淳一さんの記事を一読することをオススメします。
#本題
とはいえ、ユーザーがURLをタイポした際、「URLがまちがってまっせ」という表示をすることはユーザーフレンドリーな仕様だし、実装したい。
ということで、RailsでRoutingError時の処理を以下に書いていきます。
##HTTP 404
config/routesに記載されたルーティングのいずれも当てはまらないHTTPリクエストがRailsアプリケーションに届いた際、
例外ActionController::RoutingErrorが発生します。
HTTPステータスコード 404となります。
##rescue_fromは使わない
例外ActionController::RoutingErrorを捕捉したいですね。
安易にコピペしてよく使うrescue_fromメソッドがあります。
rescue_fromはアクションで発生した例外の補足するためのものなので、ルーティングの処理の段階で発生する例外を捕捉できません。
##config.exceptions_appで例外を捕捉する
config.exceptions_appで例外を捕捉します。
まだ勉強不足でなんとなくの理解で、詳しいことは分かりません。
以下引用です。
Rack Middleware のActionDispatch::ShowExceptionsは、config.exceptions_appに指定したオブジェクトに対して#callを呼び出して例外を捕捉する仕組みです
##config/initializer/で新たにファイルを作ろう
ともあれ、config.exceptions_appをいじればいいと分かりました。
実践です。
config/initializerディレクトリに新たなファイルを作ります。
exceptions_app.rbとします。
Rails.application.configure do
config.exceptions_app = ->(env) do
request = ActionDispatch::Request.new(env)
action =
case request.path_info
when '/404' then :not_found
else; :internal_server_error
end
ErrorsController.action(action).call(env)
end
end
受け取ったリクエストのpathが/404なら、
errorsコントローラーのnot_foundアクションを実行してね。
という処理です。
errorsコントローラー作成します
rails g controller errors
errorsコントローラーにはこのような処理を書きます
class ErrorsController < ApplicationController
def not_found
render status: 404
end
def internal_server_error
render status: 500
end
end
上記の処理で以下のファイルの内容が表示されます
view/errors/not_found.html.erb
<div id="error">
<h1>404 Not Found</h1>
<p>指定されたページは見つかりません。</p>
<p class="url"><%= request.env["REQUEST_URI"] %></p>
</div>
#rescue_from Exceptionとの違い
追記です。
NoMemoryErrorなど深刻なエラーが発生した際、どうなるか不安だったので確認しました。
開発環境はそのままNoMemoryErrorと出力されたので一安心です。
ちなみに超危険な書き方、rescue_from Exceptionも確認しみてた。
NoMemoryErrorなど発生させても、常に500 Internal Server Error と表示されるんですね。
勉強になりました。
#参考文献
Rails6実践ガイド
Railsアプリの例外ハンドリングとエラーページの表示についてまとめてみた
Railsアプリケーションにおけるエラー処理(例外設計)の考え方