Play Framework 3.0.x (以下、Play) を始めたばかりの方向けに、サンプルを進めるうえで困ったところを共有する目的で書いています。
Play にて、エラーレスポンス(クライアント、サーバー)の表示画面を、変更したときのメモです。
以下、目次
背景
ドキュメント にあるとおり、Play では、
- リクエストに対して、自動的にclient error を検出する
- アプリでの例外スローに対して、自動的にserver error を処理する
そして、エラーページを生成する。
また、別のドキュメント にあるとおり、Play では、
- 明示的な(つまり、
Action
としての)、NotFound
やInternalServerError
に対して、エラーページは生成せずに該当するエラーステータスを返す
方針
- エラーレスポンス(クライアント、サーバー)を返す際に、ほかのページと統一感のある(つまり、ヘッダー、フッター、メニュー部分が共通の)ページを表示する
- (可能なら)明示的な
NotFound
についても、ドキュメント にある、onClientError
,onServerError
を利用する
結果
ほかのページと統一感のあるページを表示する
自動生成のエラーページ => 独自のエラーページ に変更した。
これには、ドキュメントにあるとおり、
DefaultHttpErrorHandler
を拡張する か、
HttpErrorHandler
を実装する かで、実現できた。
どちらを使えばよいかは、ドキュメントを見ても理解できていない。
ので、判断基準として、書きやすい(または、コードを見たときに一覧性がある)もを選んだ(HttpErrorHandler
を実装した。)
onClientError
, onServerError
を明示的なNotFound 等にも利用する
Action.async { Future.successful(...) }
(のようなもの)に対して、NotFound
等を指定しているところに、HttpErrorHandler
を呼び出す処理に変更した。
これは、なにがしたかったのかというと、
- 「
HttpErrorHandler
を実装する」では、route が定義されていないパスにアクセスがあったときは、実装したerror handler が呼び出される - 「
HttpErrorHandler
を実装する」では、NotFound Action
を明示的に指定したときは(つまり、route を定義しておいて、NotFound
を返すときは)、実装したerror handler が呼び出されない
となっているものを、どちらも同じ処理にしたかったというもの。
具体的には、
class TestController @Inject() ( (省略) mcc: MessagesControllerComponents )(implicit (省略) ) extends MessagesAbstractController(mcc) { def test = Action.async { implicit request: Request[AnyContent] => play.api.mvc.Results.NotFound("レスポンス 404") } }
のような、NotFound を返している(これが、良いかどうかはわからない)個所を、
class TestController @Inject() ( (省略) mcc: MessagesControllerComponents, + errorHandler: ErrorHandler )(implicit (省略) ) extends MessagesAbstractController(mcc) { def test = Action.async { implicit request: Request[AnyContent] => - play.api.mvc.Results.NotFound("レスポンス 404") + errorHandler.onClientError(request, 404, "レスポンス 404") } }
のように、onClientError
を呼び出すようにした
できてないところ
そもそも、Action として、NotFound, InternalServerError 等を返す設計が良いかの判断ができていない。
ただ、play.api.mvc.Results.NotFound()
を用意しているということは、
そのような設計も想定しているのだろうけど。
参考にしたところ
- Main concepts for Scala - HTTP programming - Handling errors
- Error Handling in the Play Framework Using Scala
- Play ScalaErrorHandling not working for filters and action composition #6658
以上でした。