[API] 錯誤處理不要只回傳失敗
前言
在寫 API 的時候,很容易把成功流程寫得很完整,但錯誤流程只簡單回一句「失敗」。
例如:
1 | { |
這種回應對使用者不友善,對前端不友善,對未來要查問題的自己也不友善。
這篇整理一下,我覺得 API 錯誤處理至少可以注意的幾件事。
錯誤訊息要能被理解
錯誤訊息的第一個目的,是讓呼叫端知道發生了什麼事。
例如登入失敗時,如果只回:
1 | { |
前端很難判斷要顯示什麼,也不知道是帳號不存在、密碼錯誤,還是系統暫時異常。
可以改成比較明確的格式:
1 | { |
message 給人看,code 給程式判斷。
這樣前端可以根據 code 做不同處理,也不用去解析文字內容。
HTTP Status Code 要用對
API 回應不只看 body,也要看 HTTP status code。
常見可以這樣使用:
| 狀態碼 | 使用情境 |
|---|---|
| 400 | 請求格式錯誤或參數不合法 |
| 401 | 未登入或 token 無效 |
| 403 | 已登入,但沒有權限 |
| 404 | 找不到資源 |
| 409 | 狀態衝突,例如資料已存在 |
| 500 | 伺服器未預期錯誤 |
不要所有錯誤都回 200 OK,然後在 body 裡寫 success: false。
這樣雖然前端也能處理,但會讓 API 語意變得不清楚,也不利於監控工具判斷錯誤。
錯誤格式最好一致
如果每支 API 的錯誤格式都不一樣,前端處理起來會很痛苦。
例如有些 API 回:
1 | { |
有些回:
1 | { |
有些又回:
1 | { |
這會讓呼叫端需要為每種格式寫不同的解析邏輯。
比較好的做法是先定義統一格式,例如:
1 | { |
不一定每個欄位都要出現,但整體結構最好一致。
不要把敏感資訊丟給前端
錯誤訊息要清楚,但不能把內部細節全部暴露出去。
例如正式環境不應該直接回:
1 | SQL syntax error near 'users.password_hash' |
或:
1 | Object reference not set to an instance of an object at UserService.cs:line 87 |
這些資訊對使用者沒有幫助,還可能暴露系統結構。
比較好的做法是:
- 前端拿到簡潔、可理解的錯誤訊息。
- 後端 log 留下完整 exception 與 trace id。
- 必要時回傳 trace id,方便客服或工程師追查。
例如:
1 | { |
使用者看到的是可理解的訊息,工程師也能靠 trace id 查 log。
結語
API 錯誤處理不是把 exception 接住就結束了。
一個好的錯誤回應,應該要做到:
- status code 語意正確。
- 錯誤格式一致。
- message 給人看,code 給程式判斷。
- 不暴露敏感內部細節。
- 後端保留足夠 log 方便追查。
錯誤流程通常不是最開心的部分,但它會直接影響系統的可維護性與使用體驗。
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Hikari 的工程筆記!
如果您喜歡我寫的文章,幫我按個5下讚吧!感謝您的鼓勵和支持!
評論
WalineGitalk