§エラーハンドリング
HTTP アプリケーションが返すことのできるエラーは主に二つあります - クライアントエラーとサーバエラーです。クライアントエラーは接続しているクライアントがなにかおかしなことをしていることを示し、サーバエラーはサーバでなにかおかしなことが起こっていることを示します。
Play は様々な状況で - 不正な形式のヘッダー値、サポートしていないコンテントタイプ、そしてリクエストされたリソースが見つからない、などを含むクライアントエラーを自動的に検出します。また、Play は様々な状況でサーバエラーをハンドリングします - アクションコードが例外をスローすると、Play はこれをキャッチし、サーバエラーページを生成してクライアントに送信します。
Play はこれらのエラーを HttpErrorHandler
インタフェースを通じてハンドリングします。このインタフェースには onClientError
と onServerError
の二つのメソッドが定義されています。
§カスタムエラーハンドラの提供
カスタムエラーハンドラは、例えば以下のように HttpErrorHandler
を実装する ErrorHandler
というクラスをルートパッケージに作成することで提供できます:
import play.api.http.HttpErrorHandler
import play.api.mvc._
import play.api.mvc.Results._
import scala.concurrent._
class ErrorHandler extends HttpErrorHandler {
def onClientError(request: RequestHeader, statusCode: Int, message: String) = {
Future.successful(
Status(statusCode)("A client error occurred: " + message)
)
}
def onServerError(request: RequestHeader, exception: Throwable) = {
Future.successful(
InternalServerError("A server error occurred: " + exception.getMessage)
)
}
}
エラーハンドラをルートパッケージに置きたくない場合や、環境ごとに別のエラーハンドラを設定できるようにしたい場合は、application.conf
内に play.http.errorHandler
プロパティを設定することができます:
play.http.errorHandler = "com.example.ErrorHandler"
§デフォルトエラーハンドラの拡張
Play のデフォルトエラーハンドラは、そのままでも多数の便利な機能を備えています。例えば、dev モードにおいてサーバエラーが発生すると、Play は例外を引き起こしたアプリケーションコードの一部を見つけてレンダリングしようと試みるので、すぐに問題を参照して識別することができます。開発中はその機能を維持しながら、運用環境ではカスタムサーバエラーを提供したいこともあるでしょう。Play はこれを容易にするために、オーバーライドできる便利なメソッドをいくつも持つ DefaultHttpErrorHandler
を提供しているので、Play の既存の振る舞いにカスタムロジックを混ぜ込むことができます。
例えば、商用環境のみカスタマイズしたサーバエラーメッセージを表示し、開発用エラーメッセージには手を触れず、かつ指定したアクセス拒否エラーページを提供したい場合、以下のようにします:
import javax.inject._
import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router
import scala.concurrent._
class ErrorHandler @Inject() (
env: Environment,
config: Configuration,
sourceMapper: OptionalSourceMapper,
router: Provider[Router]
) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {
override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
Future.successful(
InternalServerError("A server error occurred: " + exception.getMessage)
)
}
override def onForbidden(request: RequestHeader, message: String) = {
Future.successful(
Forbidden("You're not allowed to access this resource.")
)
}
}
DefaultHttpErrorHandler
にある完全な API ドキュメントを参照して、オーバーライドして活用することのできるメソッドを確認してください。
Next: 非同期 HTTP プログラミング
このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。