1. 題目
一款 B2B 資料 API 服務數千個開發者團隊。最近一個版本上線後,支援工單出現大量「請求失敗但不知道怎麼改」的回饋;工程團隊認為返回更多內部日誌即可解決,銷售團隊則要求每個客戶客製錯誤文字。你作為產品經理,需要在不破壞現有客戶端的前提下,設計一套可操作的 API 錯誤體驗。
2. 約束與澄清
- 先區分客戶端輸入錯誤、驗證授權、限流、依賴故障與服務內部錯誤,不能把所有失敗合併成一個 500。
- 明確錯誤回應要同時服務機器處理、開發者排查與最終使用者展示三類讀者。
- 現有 SDK 與日誌格式不能立即全部升級;方案需要相容舊客戶端並支援漸進遷移。
- 不能把敏感堆疊、權杖、使用者資料或內部拓撲直接返回給呼叫方。
3. 產品診斷框架
先把問題拆成「發生了什麼、誰能修、下一步是什麼」三個層次。錯誤回應應有穩定的機器可讀代碼、面向人的安全摘要、可選的結構化詳情與支援關聯 ID;文件與 SDK 需要把代碼映射到修復動作。產品分析不只看錯誤率,還要看錯誤後恢復成功率、重複重試率、從失敗到成功的時間、每類錯誤的支援工單與版本分布。
4. 參考方案
errorResponse:
status: canonicalStatusCode
code: stableProductErrorCode
message: safeHumanSummary
details:
reason: machineActionableReason
fieldViolations: optionalFieldErrors
retryAfter: optionalDelay
requestId: supportCorrelationId
docsUrl: versionedFixGuide
clientFlow(error):
classify(error.status, error.code)
if retryable: backoffAndRetry(error.details.retryAfter)
else if fieldError: highlightFields(error.details.fieldViolations)
else: showDocsAndRequestId(error.docsUrl, error.requestId)先定義少量穩定的通用狀態碼,再用產品錯誤代碼表達可行動的原因;欄位錯誤、重試時間與文件連結放在結構化詳情中。控制台按代碼展示修復步驟,SDK 將錯誤映射為可捕獲的類型,同時保留原始代碼。服務端記錄完整診斷資訊,但只把安全摘要與關聯 ID 返回給呼叫方。
5. 取捨與發布策略
錯誤代碼越細,修復指引越精確,但版本相容與文件維護成本越高。可以先覆蓋高頻、可由開發者修復的錯誤,再為少數客戶問題補充詳情,不為每個租戶客製協定。新增欄位應向後相容;代碼語義一旦公開就應保持穩定,舊代碼繼續返回舊格式,新 SDK 再啟用結構化詳情。局部失敗回應需要謹慎設計,因為它會增加客戶端分支,只有批量 API 明確需要時才引入。
6. 驗證與觀測
- 從支援工單與呼叫日誌抽樣,給每類失敗標註「能否定位、能否修復、是否重複重試」。
- 對驗證授權、欄位校驗、限流、依賴逾時與未知異常分別編寫契約測試,驗證狀態碼、錯誤代碼與文件連結。
- 灰度新格式,比較錯誤後恢復率、重複重試率、支援工單量與 SDK 異常捕獲率。
- 監控未知錯誤代碼、舊客戶端占比、文件點擊到成功請求的轉化,以及錯誤回應是否洩露敏感欄位。
7. 常見誤區
- 只增加日誌或堆疊,卻沒有給呼叫方穩定代碼與修復動作。
- 用 HTTP 狀態碼承載所有業務語義,導致客戶端只能按字串解析。
- 為了「友好」把內部異常、權杖或完整請求參數放進錯誤訊息。
- 一次性重命名或刪除錯誤代碼,迫使舊 SDK 在升級時失效。
8. 面試評分點
能按修復責任分類錯誤
應區分輸入、權限、限流、依賴與內部故障,並說明每類錯誤的呼叫方動作與服務方責任。
能設計穩定且安全的錯誤模型
應提出機器可讀代碼、安全摘要、結構化詳情、關聯 ID 與版本化文件,同時避免洩露內部資訊。
能把體驗連接到產品指標
應使用恢復成功率、重複重試、修復時間、工單與版本分布衡量價值,而不是只看失敗率。
能規劃相容遷移
應說明舊格式相容、新 SDK 漸進啟用、灰度發布與回滾條件,並解釋何時不採用局部失敗等複雜協定。