最近 Padrino というウェブアプリケーションフレームワークを触ってます。
Padrino ではコントローラーのアクションを実行する前後に処理を実行することができます。
before do 前処理 end after do 後処理 end get :hoge do 処理 end
また、エラー時に表示されるページを指定することができます。
error 403 do render 'errors/403' end error 404 do render 'errors/404' end error 500 do render 'errors/500' end
ですが、エラー時に after
が実行されない場合があったので調べてみました。
その1. コントローラーが見つからない場合
コントローラーが見つからない場合は、404 Not Found エラーになるのですが、error 404
は実行されません。
また after
も実行されません。
プログラム内で halt 404
を行った場合は error 404
も after
も実行されます。
error 404
の代わりに not_found
を使えばコントローラーが見つからなかった場合にも実行されますが、after
は実行されません。
after
で行いたい後処理を not_found
の中にも書いておけばいいのですが、そうすると今度は halt 404
を行った場合に後処理が二回実行されてしまいます。
not_found
の後に error 404
を定義すると、halt 404
では not_found
は実行されないので次のように記述することができます。
after do 後処理 end # コントローラーが見つからない場合。 # after は実行されない。 not_found do 後処理 render 'errors/404' end # プログラム中で halt 404 した場合。 # after は実行される。 error 404 do render 'errors/404' end
なお not_found
の前に error 404
を書くと error 404
は実行されません。
記述する順番に依存するのはややこしいので not_found
を使わない方がいいかもしれません。
error Sinatra::NotFound
はコントローラーが見つからない場合にだけ実行され、halt 404
時には実行されないので、記述する順番には依存しません。
after do 後処理 end # プログラム中で halt 404 した場合。 # after は実行される。 error 404 do render 'errors/404' end # コントローラーが見つからない場合。 # after は実行されない。 error Sinatra::NotFound do 後処理 render 'errors/404' end
その2. プログラム中で例外が発生した場合
プログラム中で例外が発生した場合にも after
は実行されません。
development 環境では after
は実行されるのですが、これは development 環境では :show_exceptions
が true になっているためです。
production 環境と同じ動作をさせるために次のように設定すると、development 環境でも after
が実行されないことが確認できます。
disable :show_exceptions
例外発生時は 500 エラーになるので error 500
を書いておけばそれが実行されます。
not_found
の時と同様、プログラム内で halt 500
すると after
と error 500
の両方で後処理が実行されてしまいますが、プログラム中からわざわざ halt 500
を行うことはないと思うので、問題ないでしょう。
after do 後処理 end # halt 500 の場合 & 例外が発生した場合。 error 500 do 後処理 render 'errors/500' end
error
に数字ではなく例外クラスを指定すると、その例外が発生した時だけ実行できるので、次のようにも記述できます。
この場合は halt 500
では実行されません。
after do 後処理 end # 例外が発生した場合。 # after は実行されない。 error Exception do 後処理 render 'errors/500' end
なぜか error Exception
が nil を返す場合は after
が実行されるので、後処理を実行したいだけであれば次のように記述することもできます。
ただしこの場合は 500 のエラーページを返すことはできません。
after do 後処理 end # 例外が発生した場合。 # after が実行される。 error Exception do nil end
まとめ
- 例外発生時は
after
は呼ばれない not_found
はhalt 404
とコントローラーが見つからない場合の両方で呼ばれるerror 例外クラス
で例外発生時の処理を記述できる