§エラー処理
HTTPアプリケーションが返すエラーには、クライアントエラーとサーバーエラーの2種類があります。クライアントエラーは、接続しているクライアント側に問題があることを示し、サーバーエラーは、サーバー側に問題があることを示します。
Playは多くの場合、クライアントエラーを自動的に検出します。これには、不正なヘッダー値、サポートされていないコンテンツタイプ、見つからないリソースのリクエストなどのエラーが含まれます。また、Playは多くの場合、サーバーエラーも自動的に処理します。アクションコードが例外をスローした場合、Playはこれをキャッチし、クライアントに送信するサーバーエラーページを生成します。
Playがこれらのエラーを処理するインターフェースは、HttpErrorHandler
です。 これには、`onClientError`と`onServerError`の2つのメソッドが定義されています。
§JSON APIでのエラー処理
デフォルトでは、PlayはHTML形式でエラーを返します。
JSON APIの場合は、JSONでエラーを返す方が一貫性があります。
Playは、JsonHttpErrorHandler
という別の`HttpErrorHandler`実装を提供しています。これは、JSON形式でエラーを返します。
この`HttpErrorHandler`実装を使用するには、`application.conf`で`play.http.errorHandler`設定プロパティを次のように設定する必要があります。
play.http.errorHandler = play.http.JsonHttpErrorHandler
§HTMLとJSON、およびその他のコンテンツタイプの両方を使用する
最新のWebアプリで一般的なように、アプリケーションでHTMLとJSONを混在させて使用する場合、Playは、クライアントの`Accept`ヘッダーで指定された設定に基づいて、HTMLまたはJSONエラーハンドラーのいずれかに委任する別のエラーハンドラーを提供します。これは、次のように指定できます。
play.http.errorHandler = play.http.HtmlOrJsonHttpErrorHandler
これは、ほとんどのアプリケーションに適したデフォルトのエラーハンドラーです。
最後に、HTMLとJSONに加えて、エラーに対して他のコンテンツタイプをサポートする場合は、PreferredMediaTypeHttpErrorHandler
を拡張し、特定のコンテンツタイプのエラーハンドラーを追加してから、以下で説明するようにカスタムエラーハンドラーを指定します。
§カスタムエラーハンドラーの提供
BuiltInComponents
を使用してアプリを構築する場合は、`httpRequestHandler`メソッドをオーバーライドして、カスタムハンドラーのインスタンスを返します。
ランタイム依存性注入(例:Guice)を使用している場合、エラーハンドラーはランタイムに動的にロードできます。最も簡単な方法は、HttpErrorHandler
を実装する`ErrorHandler`というクラスをルートパッケージに作成することです。例:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import javax.inject.Singleton;
import play.http.HttpErrorHandler;
import play.mvc.*;
import play.mvc.Http.*;
@Singleton
public class ErrorHandler implements HttpErrorHandler {
public CompletionStage<Result> onClientError(
RequestHeader request, int statusCode, String message) {
return CompletableFuture.completedFuture(
Results.status(statusCode, "A client error occurred: " + message));
}
public CompletionStage<Result> onServerError(RequestHeader request, Throwable exception) {
return CompletableFuture.completedFuture(
Results.internalServerError("A server error occurred: " + exception.getMessage()));
}
}
エラーハンドラーをルートパッケージに配置したくない場合、または環境ごとに異なるエラーハンドラーを設定できるようにしたい場合は、`application.conf`で`play.http.errorHandler`設定プロパティを設定することでこれを行うことができます。
play.http.errorHandler = "com.example.ErrorHandler"
§デフォルトのエラーハンドラーの拡張
Playのデフォルトのエラーハンドラーは、すぐに使える多くの便利な機能を提供します。たとえば、開発モードでは、サーバーエラーが発生した場合、Playはアプリケーション内でその例外の原因となったコード部分を特定してレンダリングしようとします。これにより、問題をすばやく確認して特定できます。本番環境ではカスタムサーバーエラーを提供しながら、開発環境ではその機能を維持したい場合があります。これを容易にするために、PlayはDefaultHttpErrorHandler
を提供しています。これには、カスタムロジックをPlayの既存の動作と組み合わせることができるようにオーバーライドできる便利なメソッドがいくつかあります。
たとえば、本番環境でカスタムサーバーエラーメッセージを提供するだけで、開発エラーメッセージには手を加えず、特定の禁止エラーページも提供したい場合
import com.typesafe.config.Config;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import javax.inject.*;
import play.*;
import play.api.OptionalSourceMapper;
import play.api.UsefulException;
import play.api.routing.Router;
import play.http.DefaultHttpErrorHandler;
import play.mvc.*;
import play.mvc.Http.*;
@Singleton
public class ErrorHandler extends DefaultHttpErrorHandler {
@Inject
public ErrorHandler(
Config config,
Environment environment,
OptionalSourceMapper sourceMapper,
Provider<Router> routes) {
super(config, environment, sourceMapper, routes);
}
protected CompletionStage<Result> onProdServerError(
RequestHeader request, UsefulException exception) {
return CompletableFuture.completedFuture(
Results.internalServerError("A server error occurred: " + exception.getMessage()));
}
protected CompletionStage<Result> onForbidden(RequestHeader request, String message) {
return CompletableFuture.completedFuture(
Results.forbidden("You're not allowed to access this resource."));
}
}
オーバーライド可能なメソッドと、それらをどのように活用できるかを確認するには、DefaultHttpErrorHandler
の完全なAPIドキュメントを参照してください。
このドキュメントに誤りを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを送信してください。質問やアドバイスがあれば、コミュニティフォーラムにアクセスして、コミュニティとの会話を始めてください。