NET8 WebAPI 錯誤訊息回應研究
引言
又一個無言以對的問題。若 WebAPI 執行都成功如預期那就好辦了。 實際上會有失敗的狀況,而錯誤訊息回應並沒有標準答案也沒有通同典範。 剛好有機會就研究一下。
論 HTTP Status Code
HTTP Status Code 指向成功的代碼有 200, 204,這 200 是文字、HTML、JSON、FILE 由工程師決定,這在實務上沒有問題,因為已預期成功送回的格式。 HTTP Status Code 指向失敗的代碼有 4XX, 5XX 一大堆。對工程師有意義的只有 400, 422, 500。簡介如下:
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!!! 。
簡述封包送到前端的解析動作
把 ValidationProblem(...) 預設回傳 status code 由 400 BadRequest 改成 422 UnprocessableEntity 應該也合理,只是多一些沒有實際意義的描述。
其中 Problem 的訊息規格是有學理規範的。RFC 9110: HTTP Semantics。
https://datatracker.ietf.org/doc/html/rfc9110#section-15.5.1
結論的結論
一般用下面指令與格式送回封包就可以了,暨符合學理又實務。權限相關的 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