GH GambleHub

錯誤處理和狀態代碼

1)為什麼要標準化錯誤

單一錯誤合同加快了客戶調試,減少了虛假的重復並使RCA可播放。良好的系統:
  • 可以預見地編碼問題的類型,
  • 向客戶提供有效的提示(接下來要做什麼),
  • 防止內部零件泄漏,
  • 與復古和冪等兼容。

2)設計原則

1.所有服務的一個錯誤模式(REST/GraphQL/gRPC/webhooks)。
2.清晰的retrae語義:哪些代碼是retra,哪些不是。
3.在寫操作上失效:優於4xx/5xx而不是安靜的非約束。
4.不泄漏:不披露SQL、堆棧、configs、內部ID。
5.跟蹤:始終返回'trace_id'/'correlation_id'。
6.消息本地化-可選,但代碼和「reason」保持穩定。


3)統一格式(問題詳細信息/JSON)

推薦的基本格式(與RFC 7807兼容):
json
{
"type": "https://errors.example.com/auth/invalid-token",
"title": "Invalid access token",
"status": 401,
"code": "AUTH_INVALID_TOKEN",
"detail": "Token expired or signature invalid.",
"instance": "/api/v1/payments/12345",
"trace_id": "01HX3...ABC",
"hint": "Obtain a new token via OAuth2 refresh.",
"meta": {
"scope": "payments:write",
"policy": "deny-by-default"
}
}
說明:
  • 「類型」是錯誤類的穩定URL ID。
  • 「代碼」是短域機器代碼(版本之間穩定)。
  • 「hint」-客戶端要做什麼(重播、更新令牌、更改設置)。
  • 「meta」是安全的細節(沒有秘密和PII)。

4)狀態代碼映射(最低設置)

身份驗證/授權

400 Bad Request是結構驗證/方案。
401 Unauthorized-無/非驗證令牌。添加「WWW-Authenticate」。
403 Forbidden-已身份驗證,但沒有權利/政策被拒絕。
404 Not Found-在沒有權限的情況下掩蓋資源的存在。
409沖突是版本/狀態沖突(optimistic lock,等效性)。
451 Unavailable For Legal Reasons是一個合規性/管轄區塊。

限制和保護

408 Request Timeout-客戶端發送主體的速度太慢。

409/425 Too Early-第一0-RTT/TLS禁止早期重播。3.

429 Too Many Requests-帶有「Retry-After」和限制政策。
499 Client Closed Request-(在外圍/NGINX)客戶端斷開連接。

數據和業務規則

422 Unprocessable Content-業務驗證已通過該方案,但含義不正確。
423 Locked-資源鎖定(KYC review, AML freeze)。
409沖突是雙重發送,競賽,狀態限制(例如,「已經在處理中」)。
410 Gone-已刪除端口/資源(刪除已完成)。

服務器

500 Internal Server Error-未知錯誤;不要透露細節。
502 Bad Gateway-依賴性返回錯誤/滾動。
503 Service Unavailable-退化/計劃工作;添加「Retry-After」。
504 Gateway Timeout-依賴時間。

💡 規則:write操作,如果有疑問→ 409(沖突)或503(重播後),不是200。

5)靜止和靜止語義

無法轉發:400/ 401/403/404/422(如果客戶沒有更改請求)。
可以轉發:408/429/5xx/ 425/499/504(帶有backoff+jitter)。
相似性:對於「POST」,請啟用「Idempotency-Key」(UUIDv4)。

對於重新運行沖突,請返回409,並帶有「hint:使用字符標識-鍵或GET狀態」。
返回保存的結果時添加「Idempotency-Replay: true」。

429的頭部示例:

HTTP/1.1 429 Too Many Requests
Retry-After: 3
RateLimit-Limit: 50
RateLimit-Remaining: 0
RateLimit-Reset: 1730641030

6)入口驗證: 字段錯誤結構

對於400/422,請使用字段錯誤數組:
json
{
"type": "https://errors.example.com/validation",
"title": "Validation failed",
"status": 422,
"code": "VALIDATION_ERROR",
"trace_id": "01HX4...XYZ",
"errors": [
{"field": "amount", "rule": "min", "message": "Must be >= 10"},
{"field": "currency", "rule": "enum", "message": "Unsupported currency"}
]
}

7)部分失敗(batch/partial failure)

在戰鬥結束中,不要在沒有結構的情況下將錯誤隱藏在200內。返回207 Multi-Status或200 c結果陣列,其中每個作業都有自己的狀態:
json
{
"status": "partial",
"succeeded": 8,
"failed": 2,
"results": [
{"id": "op1", "status": 201},
{"id": "op2", "status": 422, "error": {"code":"VALIDATION_ERROR","detail":"..."}}
]
}

8)分割和「空白」答案

空白收藏是200,帶有「items:[]」,不是404。
頁面結尾為「next_page_token」。
不正確的令牌是400 code: PAGINATION_CURSOR_INVALID'。


9) Webhooks: 可靠的交付

簽署事件(HMAC)並在處理前檢查。
成功處理的答案是2xx(優於204)。
收件人的時間故障為5xx;發件人重復(指數backoff,jitter)。
通過「event_id」進行重復數據消除並保存結果(idempotent consumer)。
payload無效-400/422,沒有重復。


10)協議合規性(gRPC/GraphQL)

gRPC → HTTP:

`INVALID_ARGUMENT` → 400

`UNAUTHENTICATED` → 401

`PERMISSION_DENIED` → 403

`NOT_FOUND` → 404

`ALREADY_EXISTS` → 409

`FAILED_PRECONDITION` → 412/422

`RESOURCE_EXHAUSTED` → 429

`ABORTED` → 409

`UNAVAILABLE` → 503

`DEADLINE_EXCEEDED` → 504

GraphQL:在傳輸層中始終允許200個,但在「errors[]」中放置錯誤,並在標題/擴展中復制:
json
{
"data": { "createPayment": null },
"errors": [{
"message": "Forbidden",
"extensions": { "code": "FORBIDDEN", "status": 403, "trace_id": "..." },
"path": ["createPayment"]
}]
}

對於嚴重錯誤,建議不要使用200,而是使用相應的HTTP代碼。


11)標題和提示客戶

「Retry-After」-秒/NTTR日期(429/503/425/408)。
「警告」是軟降解或去除(「199-Feature X已去除」)。
`Deprecation`, `Sunset`, `Link: <...>;rel=「deprecation」'-用於受控斷開連接。
「問題類型」(定制)-快速路由客戶端上的錯誤。
「X-Trace-Id」/「Correlation-Id」-鏈接徽標/Trays。


12)通訊安全

不要重復響應主體中的輸入秘密(令牌/簽名)。
偽裝PAN/PII('1234')。
對於401/403,請勿透露失敗的屬性。
對於404,而不是「資源輸出而不是您自己」-只是404。


13)錯誤的可觀察性

度量標準:
  • `http_errors_total{status, route, tenant}`
  • 'error_classes_total {code}(來自主體的'code')
  • 429, 5xx; 'p95'/'p99 'latency分配給錯誤答案
  • 'retry_after_seconds_bucket'-重復提示直方圖
Logi/Traces:
  • 將響應鏈接到「trace_id」,存儲「code」,「type」,「status」,「route」,「tenant」,而不存儲PII。
Alerts:
  • RPS> N下的'5xx_rate> X%'激增;
  • 在關鍵路線上增加429條;
  • 依賴關系中的「timeout/504」;
  • 頻繁的409/偶數 →比賽的標誌。

14)示例

14.1,422(業務驗證)

json
{
"type": "https://errors.example.com/payments/limit-exceeded",
"title": "Limit exceeded",
"status": 422,
"code": "PAYMENT_LIMIT_EXCEEDED",
"detail": "Daily withdrawal limit reached for KYC1.",
"hint": "Increase limits after KYC2 or try tomorrow.",
"trace_id": "01J5...XYZ"
}

14.2 409(等容)


HTTP/1.1 409 Conflict
Idempotency-Replay: true
json
{
"type": "https://errors.example.com/idempotency/replay",
"title": "Duplicate request",
"status": 409,
"code": "IDEMPOTENT_REPLAY",
"detail": "A request with the same Idempotency-Key was already processed.",
"hint": "Reuse the same Idempotency-Key and GET the operation status."
}

14.3,429(限額)

json
{
"type":"https://errors.example.com/rate/too-many-requests",
"title":"Too many requests",
"status":429,
"code":"RATE_LIMITED",
"detail":"Per-key rate limit exceeded.",
"hint":"Retry after the time specified in Retry-After header."
}

15)反模式

返回200和主體中的錯誤文本。
在服務之間混合不同的錯誤格式。
在「詳細信息」中披露堆棧/SQL/表名/內部 URL。
使用「消息」代替穩定的「代碼」/「類型」。
在預期業務錯誤時返回500(例如,「資產負債表不足」)。
REST/GraphQL/gRPC之間的語義不一致。


16) iGaming/財務細節

KYC/AML/制裁的明確代碼是:「KYC_REQUIRED」,「KYC_REVIEW」,「AML_LOCK」,「SANCTION_BLOCKED」。
管轄權限制:451,措辭安全,沒有指定清單。
現金寫作交易:409/423在競爭和鎖定中,帶有重播窗口的「hint」。
玩家限額不變量:使用422違反負責任支付規則。
審計:不變的決策日誌(代碼、時間、演員、trace_id)。


17)準備就緒支票清單

  • 單個JSON誤差圖,穩定的「類型」/「代碼」。
  • Mapping HTTP ↔ gRPC/GraphQL是一致且有記錄的。
  • retrae+「Retry-After」的語義;write的等效性。
  • 偽裝PII/秘密;404用於隱藏資源。
  • 錯誤和異常度量;以「trace_id」表示。
  • Deprecate政策:「Deprecation」,「Sunset」,「Link」。
  • 測試:negative/fuzz,版本沖突,依賴性下降,雙次提交。
  • 海德客戶:回收和處理409/422/429/5xx。

18) TL;DR

將單個JSON錯誤格式c'type'/'code'/'trace_id'標準化,使用正確的HTTP代碼,區分驗證(400/422), (401/403/404)、沖突/等效性(409)和限制(429)。讓我們明確的「Retry-After」和「hint」,掩蓋敏感數據,用「trace_id」繪制錯誤,並在5xx/429/p99上構建變量。

Contact

與我們聯繫

如有任何問題或支援需求,歡迎隨時聯絡我們。我們隨時樂意提供協助!

開始整合

Email 為 必填。Telegram 或 WhatsApp 為 選填

您的姓名 選填
Email 選填
主旨 選填
訊息內容 選填
Telegram 選填
@
若您填寫 Telegram,我們將在 Email 之外,同步於 Telegram 回覆您。
WhatsApp 選填
格式:國碼 + 電話號碼(例如:+886XXXXXXXXX)。

按下此按鈕即表示您同意我們處理您的資料。