ドキュメント

§エラー処理

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ドキュメントを参照してください。

次:アプリケーションのテスト


このドキュメントに誤りを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを送信してください。質問やアドバイスがあれば、コミュニティフォーラムにアクセスして、コミュニティとの会話を始めてください。