文件

§處理錯誤

HTTP 應用程式可以傳回兩種主要類型的錯誤 - 伺服器端錯誤和用戶端錯誤。用戶端錯誤表示連線的用戶端做錯了某些事,伺服器端錯誤表示伺服器端出了問題。

在許多情況下,Play 會自動偵測用戶端錯誤 - 這些錯誤包括格式錯誤的標頭值、不支援的內容類型,以及對找不到的資源提出的要求。在許多情況下,Play 也會自動處理伺服器端錯誤 - 如果您的動作程式碼擲回例外,Play 會擷取此例外並產生伺服器端錯誤頁面傳送給用戶端。

Play 處理這些錯誤的介面是 HttpErrorHandler。它定義了兩個方法,onClientErroronServerError

§處理 JSON API 中的錯誤

預設情況下,Play 會以 HTML 格式傳回錯誤。
對於 JSON API,以 JSON 格式傳回錯誤會更一致。

Play 提出了另一個 HttpErrorHandler 實作,稱為 JsonHttpErrorHandler,它會傳回以 JSON 格式化的錯誤。

若要使用該 HttpErrorHandler 實作,您應該在 application.conf 中設定 play.http.errorHandler 設定屬性,如下所示

play.http.errorHandler = play.http.JsonHttpErrorHandler

§同時使用 HTML 和 JSON,以及其他內容類型

如果您的應用程式同時使用 HTML 和 JSON,這在現代網路應用程式中很常見,Play 提供另一個錯誤處理常式,它會根據客戶端 Accept 標頭中指定的偏好設定,委派給 HTML 或 JSON 錯誤處理常式。這可以用以下方式指定

play.http.errorHandler = play.http.HtmlOrJsonHttpErrorHandler

這是大多數應用程式的合適錯誤處理常式預設選項。

最後,如果您想要支援除了 HTML 和 JSON 之外的其他錯誤內容類型,您可以延伸 PreferredMediaTypeHttpErrorHandler,並針對特定內容類型新增錯誤處理常式,然後指定自訂錯誤處理常式,如下所述。

§提供自訂錯誤處理常式

如果您使用 BuiltInComponents 來建構您的應用程式,請覆寫 httpRequestHandler 方法以傳回您的自訂處理常式的執行個體。

如果您使用執行時期依賴注入(例如 Guice),則可以在執行時期動態載入錯誤處理常式。最簡單的方式是在根目錄中建立一個名為 ErrorHandler 的類別,實作 HttpErrorHandler,例如

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 文件,以查看有哪些方法可以覆寫,以及如何利用它們。

下一步:測試您的應用程式


在這個文件中發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時提交拉取請求。有問題或建議想要分享?請前往 我們的社群論壇 與社群展開對話。