Game-as-a-Service / Lobby-Platform-Service

The Lobby platform backend of Game as a Service.
https://api.gaas.waterballsa.tw/swagger-ui/index.html
Apache License 2.0
30 stars 7 forks source link

Global Exception Handler Response Format #119

Closed ricksu978 closed 1 year ago

ricksu978 commented 1 year ago

參考資料之一 https://www.baeldung.com/rest-api-error-handling-best-practices

除了設計格式,還有重點思考 回傳 4xx & 5xx 的條件,甚麼時候該回傳 4xx 甚麼時候該回傳 5xx? 希望能有「具體」的規則可循。

m1a2st commented 1 year ago

參考資料 https://josipmisko.com/posts/rest-api-error-handling 節錄重點

Should the response body include the HTTP status code? The response body should not include the HTTP status code. Including it in the response body adds to the network payload and it is redundant. Should error response include the exception message? Based on RFC7807, error response should not include the exception message or stack trace

m1a2st commented 1 year ago

參考資料 https://datatracker.ietf.org/doc/html/rfc7807

{
    "type": "https:example.com/probs/out-of-credit",
    "title": "You do not have enough credit.",
    "detail": "Your current balance is 30, but that costs 50.",
    "instance": "/account/12345/msgs/abc",
    "balance": 30,
    "accounts": ["/account/12345",
                 "/account/67890"]
}
m1a2st commented 1 year ago

Java Exception 分為

今天要處理的都是運行時異常

Http Status Code

先不考慮 Error 的情況,發生 Error 的狀況時,伺服器應該就直接掛點。

若編譯時異常直接向外拋出,給 AOP 處理時,我認為狀態碼應該要屬於 5XX

而一般運行時異常,像是 NullPointerException, ArrayIndexOutOfBoundedException,也應該屬於伺服器端錯誤 所以此類狀態碼也應該為 5XX

而應該拋出 4XX 異常的應為

常見回傳狀態碼

有可能後續會需要的狀態碼

Exception Message

bealung

{
  "timestamp": "2020-01-01T00:00:00.000+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "Exception Message",
  "path": "/api/v1/xxx"
}

rfc7807

{
  "type": "https://example.com/probs/out-of-credit",
  "title": "You do not have enough credit.",
  "detail": "Your current balance is 30, but that costs 50.",
  "instance": "/account/12345/msgs/abc",
  "balance": 30,
  "accounts": ["/account/12345", "/account/67890"]
}

myself

{
  "timestamp": "2020-01-01T00:00:00.000+0000",
  "httpMethod" : "GET",
  "path": "/api/v1/xxx",
  "title": "You do not have enough credit.",
  "message": "Your current balance is 30, but that costs 50."
}
ricksu978 commented 1 year ago

而一般運行時異常,像是 NullPointerException, ArrayIndexOutOfBoundedException,也應該屬於伺服器端錯誤 所以此類狀態碼也應該為 5XX

而應該拋出 4XX 異常的應為

  • 自定義例外,如 NotFoundexcption, PlatFormException 不影響程式運作的例外
  • @Valid 檢查而拋出的例外也應為 4XX

讚!

m1a2st commented 1 year ago

跟Rick討論完,暫定結果

{
  "timestamp": "2020-01-01T00:00:00.000+0000",
  "errorCode": "U0001",
  "message": "Your current balance is 30, but that costs 50."
}