課題
Rails + postgresql で Rail アプリが起動中に postgresql が停止してしまった場合、productio モード、development モードでこんな画面が出る。
production モード
develoment モード
development 時は これでもよいが、production モードの画面は、カスタマイズしたい場合がある。
こんな画面にする例を作ってみる。
カスタマイズしたエラー画面
実装ポイント
実装例は https://github.com/katoy/rails-canvas に置いた。
Postgresql 接続のエラーは controller 部ではキャッチできない。
そこで、 rake middleware に PG::ConnectioBad 例外をキャッチする rack アプリを登録する。
その rack アプリでは、サイトの画面テンプレートでレイアウトした画面を表示する。-
- class DatabaseFailure を登録する。
- これを 次のようにして登録する。
config.middleware.insert_before ActiveRecord::ConnectionAdapters::ConnectionManagement, ActionDispatch::Rescue do
rescue_from PG::ConnectionBad, DatabaseFailure
end
変更と加える前の rake middleware の出力結果と、変更後の rake middleware の出力結果を比較する。
Rescue アプリが追加された事がわかる。
- 変更前
...
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
...
- 変更後
...
use ActionDispatch::Callbacks
use ActionDispatch::Rescue
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
...
動作確認
- postgressqlを稼働させる。rake s で rails アプリを稼働させる。
(postgresql が 未稼働だと、rails 開始時にエラーになってしまう。) - rails を稼働させる。
$ bundle install
$ bundle exec rake db:drop db:create db:migrate db:fixtures:load
$ rails s
http://localhost:3000 に web browser でアクセスして、正常な画面が出る事を確認する。
- その状態で、 postgresql を停止する。
- 再度、 http://localhost:3000 にアクセスする。
カスタマイズした画面が出ることが確認できる。
参考
- http://irohiroki.com/2011/06/15/rescue-rack-middleware-exceptions Rack middlewareで発生する例外をrescueする
...
例えばMySQLを使っていてデータベースサーバに接続できない場合、
ActiveRecord::ConnectionAdapters::ConnectionManagementというmiddlewareから
Mysql2::Errorが発生します。
...
つまり、どうやってもアプリケーションではrescueできません。
...
Rack middlewareで発生した例外はActionDispatch::Rescueというmiddlewareで捕捉できます。ActionDispatch::ShowExceptionsと違い、ActionDispatch::Rescueは例外クラスに対してハンドリングするRackアプリケーションを指定できます。
...
- http://yuuxxxx.hatenablog.com/entry/2013/08/29/205741 404ページ、500ページのつくりかた rails の controller で捕捉できるエラーについて、 404, 500 の画面は、このページで述べられている方法で対処できる。