Railsのエラーハンドリング
Rails3.2から結構いい感じになったエラーハンドリング
Railsは1.xからやっているけど、気に喰わないのがエラーハンドリング周りだった。 特にRoutingエラーを補足する為に各バージョンごとに対応が微妙に違ったりして、毎回調べたりRailsの実装を追っていた記憶がある。 だけどRails3.2から実装された機能で、個人的にはこれで落ち着いたかなと思えた。 既に4が出ているので今更感があるけど、備忘録として書いておく。 Rails4.0.2,Ruby2.0.0で確認しています。
Release Notesでは以下のように書かれている。
Added config.exceptions_app to set the exceptions application invoked by the ShowException middleware when an exception happens. Defaults to ActionDispatch::PublicExceptions.new(Rails.public_path).
つまり、例外発生時に呼ばれる例外処理アプリケーションを config.exceptions_app で設定できるようになった。 デフォルトではActionDispatch::PublicExceptions.new(Rails.public_path)が設定される。
どうやって使うか
色々と調べた結果、ActionDispatch::Routing::RouteSetをセットしてやるのが一番シンプルかなーと思った。 まずはself.routesをセット。
# config/application.rb config.exceptions_app = self.routes #=>ActionDispatch::Routing::RouteSet
で、例外処理用のコントローラを作成しておく。
# app/controllers/erros_controller.rb class ErrorsController < ApplicationController def not_found render status: 404 end def internal_server_error render status: 500 end end
最後にroutes.rbで各httpステータスコードを判定し、ErrorsControllerの各メソッドを指定してやる。
# config/routes.rb get '/404', to: 'errors#not_found' get '/500', to: 'errors#internal_error'
他のやり方
self.routes以外を指定する事も当然出来る。 というかRackアプリを指定できるのでRailsで無くてもOKです。 例えば以下の様な感じ。
# config/application.rb config.exceptions_app = ->(env) { ErrorsController.action(:error_page).call(env) }
明確にエラーコードを表示したいウェブアプリだと使うかも。
思うこと
エラーハンドリングに関してはRails newした時に雛形を作るなどしてしまってもいいのではと思った。フリーランスで働いていた時に、途中から入ったプロジェクトの場合、エラーハンドリングの実装方法がバラバラで、その内容によっては無駄に工数がかかるケースもあったので。 ま、Rails is omakaseなので嫌なら使うなって話ですが。