簡體   English   中英

如何在Cloud Endpoints中返回自定義錯誤代碼?

[英]How to return custom error codes in Cloud Endpoints?

如此處所述https://cloud.google.com/appengine/docs/java/endpoints/exceptions Google Cloud Endpoints僅返回非常有限的http狀態代碼范圍,即:

HTTP 400 BadRequestException
HTTP 401 UnauthorizedException
HTTP 403 ForbiddenException
HTTP 404 NotFoundException (also: Timeout)
HTTP 405
HTTP 408
HTTP 409 ConflictException
HTTP 410
HTTP 412
HTTP 413

Google建議使用現有狀態代碼返回自定義錯誤:

“在許多情況下,您可能希望使用常見的HTTP狀態代碼來指示用戶的API請求是成功還是失敗。例如,如果用戶嘗試檢索不存在的實體,則可能希望發送HTTP 404狀態碼,表示不存在ID為EntityId的實體,您可以通過拋出端點庫提供的異常來發送此類常見的HTTP狀態碼,如下所示:

String message = "No entity exists with ID: " + entityId;
throw new NotFoundException(message);

在同一文檔中,Google進一步聲明:

“任何其他HTTP 4xx代碼將作為錯誤404返回”

這是什么問題? 如果找不到我的實體,我會拋出404,但是Google也會為幾乎所有其他出錯的地方拋出404。

除了401、403和409(我可以用來告訴我的客戶確切的錯誤是什么(授權,禁止或沖突))之外,對於其他所有狀態代碼,我需要分別使用400和404,結果是我的客戶永遠不知道到底是什么問題。

當然,我可以包括一條人類可讀的錯誤消息,但這是針對服務器代碼中發生的RuntimeException的,而不是告訴我的客戶端它發送的數據有問題。

當然,我也可以使用錯誤描述的前幾位來發送特定於應用程序的錯誤代碼並發送通用的400 Bad Request,但是我想這不是應該這樣做的方式。

任何輸入表示贊賞。 您如何返回客戶可以用來解決特定於應用程序的問題的特定於應用程序的錯誤代碼?

閱讀了以下內容和其他帖子

我幾乎可以說Google的建議是錯誤的,因為http狀態代碼和應用程​​序代碼之間沒有明顯的區別。 兩者都發生在不同的層上,並且客戶端無法告知是否發出了錯誤的請求,例如違反合同(例如,調用不存在的端點,本質上是運行時錯誤)或傳遞錯誤的ID(應用程序層)錯誤)。

文章提出了以下解決方案:

  • 使用http錯誤代碼:如上所述並非總是可能的
  • 將應用程序錯誤添加為自定義響應標頭:我不會選擇它,因為它不會出現在日志中,這會使調試變得困難。
  • 總是返回200並將結果包裝在JSON中(就像sockets.io一樣):在端點上不可行

我提出了另一個解決方案,我承認這是一個折衷方案(實際上是違反錯誤消息),但是我認為這是將各個應用程序錯誤代碼最合適地集成到Cloud Endpoints中的一種解決方案:

  • 我擴展了400 BadRequestException,以便將任何錯誤消息作為JSON返回。 客戶端仍然接收到HTTP狀態代碼400,但是它接收到的是JSON字符串,而不是String錯誤消息:

{“代碼”:400,“消息”:“這是人類可讀的錯誤消息。” }

這里有兩個選項:或者返回代碼400,這意味着客戶端實際上違反了合同,這是BadRequestException,或者返回了客戶端可以輕松解析和處理的任何其他應用程序特定代碼。

我的ApplicationException看起來像這樣(它使用了自定義的JSONizer,因此它對您不起作用,但是您可以使用JSONObject,GSON,Jackson等):

import com.google.api.server.spi.response.BadRequestException;

public class ApplicationException extends BadRequestException {
    private static final int DEFAULT_APPLICATION_CODE = 400; // use this code for all requests without explicit code

    public ApplicationException(int code, String message) {
        super(JsonResponse.build()
                .add("code", code)
                .add("message", message)
                .toString());
    }
    public ApplicationException(String message) {
        super(JsonResponse.build()
                .add("code", DEFAULT_APPLICATION_CODE)
                .add("message", message)
                .toString());
    }
    public ApplicationException(String message, Throwable cause) {
        super(JsonResponse.build()
                .add("code", DEFAULT_APPLICATION_CODE)
                .add("message", message)
                .toString());
    }

}

我尚未將答案標記為正確,因為如果您認為有更好的方法可以繼續發表進一步的建議和意見。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM