NET8 WebAPI 錯誤訊息回應研究

引言

又一個無言以對的問題。若 WebAPI 執行都成功如預期那就好辦了。 實際上會有失敗的狀況,而錯誤訊息回應並沒有標準答案也沒有通同典範。 剛好有機會就研究一下。

論 HTTP Status Code

HTTP Status Codearrow-up-right 指向成功的代碼有 200, 204,這 200 是文字、HTML、JSON、FILE 由工程師決定,這在實務上沒有問題,因為已預期成功送回的格式。 HTTP Status Code 指向失敗的代碼有 4XX, 5XX 一大堆。對工程師有意義的只有 400, 422, 500。簡介如下:

HTTP Status Code
論述

200 OK

格式未知,不過可預期實務上沒有問題。

204 NoContent

成功,沒有回傳內容。實務上是有的。

400 Bad Request

格式未知,也不可預期,實務上問題可大了。

401 Unauthorized

未授權。一般指未登入。(不在本文討論)

403 Forbidden

授權不足。一般指已登入但權限不夠不能執行某些功能。(不在本文討論)

404 Not Found

功能不存在。(不在本文討論)

422 Unprocessable Entity / Unprocessable Content

文字描述有二種不過意義是一樣的,就是客戶端給的封包不能處理。 原因當然是封包內容驗證失敗。送回錯誤原由建議用 JSON 送回。

500 Internal Server Error

基本上是系統級錯誤,一般轉成文字再處置。

先下結論

以 Web API 來說, 成功訊息就回傳 200 JSON object。若是下載檔案也是預期之中看是 byte[] 還是 stream 都是預期之中。 另一個成功訊息 204 NoContent 也是預期之中的格式處置上沒有問題。 失敗訊息可能是4xx或5xx。建議直接送回以文字解析就好,不強改 status code 因為可能發生預期之外的系統級例外。進一步的失敗訊息可用 422 送回 JSON 格式的錯誤訊息,比如放表單的 validation message。

回應指令成功指令有2個 Ok(),NoContent(),不過失敗指令有數個:BadRequest()UnprocessableEntity()ValidationProblem()Problem()、throw out exception!!! 。

簡述封包送到前端的解析動作

circle-info

ValidationProblem(...) 預設回傳 status code 由 400 BadRequest 改成 422 UnprocessableEntity 應該也合理,只是多一些沒有實際意義的描述。

circle-info

其中 Problem 的訊息規格是有學理規範的。RFC 9110: HTTP Semantics。

https://datatracker.ietf.org/doc/html/rfc9110#section-15.5.1arrow-up-right

結論的結論

一般用下面指令與格式送回封包就可以了,暨符合學理又實務。權限相關的 401, 403, 404 等不在本文討論。


回傳指令與回應封包紀錄

Ok(JSON) ==> 200; application/json;

Ok(TEXT) ==> 200; text/plain;

NoContent() ==> 204;

BadRequest(JSON)==> 400; application/json;

BadRequest(TEXT)==> 400; text/plain;

UnprocessableEntity(JSON)==> 422; application/json;

UnprocessableEntity(TEXT)==> 422; text/plain;

ValidationProblem(TEXT)==> 400; application/problem+json;

ValidationProblem(this.ModelState)==>400; application/problem+json;

Problem(TEXT) ==>500; application/problem+json;

throw out ==>500; text/plain;


附上測試程式碼

(EOF)

Last updated