Σφάλμα χειρισμού και κωδικών κατάστασης
1) Γιατί να τυποποιηθούν τα σφάλματα
Ένα μόνο συμβόλαιο σφάλματος επιταχύνει την αποσφαλμάτωση πελατών, μειώνει τις ψευδείς ρετράι και κάνει την RCA να μπορεί να παίξει. Καλό σύστημα:- κωδικοποιεί προβλέψιμα το είδος του προβλήματος,
- παρέχει στον πελάτη έγκυρα κίνητρα (τι θα κάνει στη συνέχεια),
- προστατεύει από διαρροή εσωτερικών μερών,
- συμβατό με ρετράς και ιδιοτέλεια.
2) Αρχές σχεδιασμού
1. Ένα σύστημα σφάλματος για όλες τις υπηρεσίες (REST/GraphQL/gRPC/webhooks).
2. Σαφής σημασιολογία των retrays: ποιοι κωδικοί θα αποσυρθούν, ποιοι όχι.
3. Αποτυχία-κλείσιμο σε λειτουργίες εγγραφής: καλύτερα 4xx/5xx από ήσυχη ασυνέπεια.
4. Χωρίς διαρροές: Μη αποκαλύψετε SQL, στοίβες, ρυθμίσεις, εσωτερικές ταυτότητες.
5. Εντοπισμός - Πάντα επιστροφή 'trace _ id '/' συσχέτιση _ id'.
6. Η τοπικοποίηση των μηνυμάτων είναι προαιρετική, αλλά οι κωδικοί και η επανάληψη παραμένουν σταθεροί.
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"
}
}
Επεξηγήσεις:
- 'type' είναι μια κατηγορία σταθερού σφάλματος URL.
- 'κώδικας' - κωδικός μηχανής μικρού πεδίου (σταθερός μεταξύ των απελευθερώσεων).
- «υπόδειξη» - τι να κάνετε για τον πελάτη (επανάληψη, ενημέρωση της μάρκας, παράμετροι αλλαγής).
- «meta» - ασφαλή μέρη (χωρίς μυστικά και PII).
4) Χάρτης κωδικών κατάστασης (ελάχιστο σύνολο)
Ταυτοποίηση/εξουσιοδότηση
400 Κακή αίτηση - δομική επικύρωση/σύστημα.
401 Μη εξουσιοδοτημένη - όχι/άκυρη μάρκα. Προσθήκη 'WWW-Authenticate'.
403 Απαγορευμένη - επικυρωμένη αλλά χωρίς δικαιώματα/πολιτικές που απορρίπτονται.
404 Δεν βρέθηκε - συγκαλύψτε την ύπαρξη ενός πόρου χωρίς δικαιώματα.
409 Σύγκρουση - έκδοση/κρατική σύγκρουση (αισιόδοξη κλειδαριά, ιδεατότητα).
451 Μη διαθέσιμο για νομικούς λόγους - Ενότητα συμμόρφωσης/δικαιοδοσίας.
Όρια και προστασία
408 Χρονοδιάγραμμα αιτήσεων - Ο πελάτης στέλνει το σώμα πολύ αργά.
409/425 - Απαγόρευση της πρόωρης επανάληψης στην 0-RTT/TLS 1. 3.
429 Πάρα πολλά αιτήματα - με «Retrip-After» και περιορισμένη πολιτική.
499 Κλειστό αίτημα πελάτη - (στην περίμετρο/NGINX) ο πελάτης αποσύνδεσε τη σύνδεση.
Κανόνες για τα δεδομένα και τις επιχειρήσεις
422 Μη βιώσιμο περιεχόμενο - η επικύρωση της επιχείρησης πέρασε από το σύστημα, αλλά το νόημα είναι εσφαλμένο.
423 Κλειδωμένοι - φραγμένοι πόροι (ανασκόπηση KYC, πάγωμα AML).
409 Σύγκρουση - διπλή υποβολή, φυλή, όριο κατάστασης (για παράδειγμα, «ήδη σε εξέλιξη»).
410 Εξαφανίστηκε - το τελικό σημείο/ο πόρος διαγράφηκε (αφαιρέστε το πλήρες).
Εξυπηρετητής
Σφάλμα εσωτερικού εξυπηρετητή 500 - άγνωστο σφάλμα. δεν αποκαλύπτουν λεπτομέρειες.
502 Κακή πύλη - εξάρτηση επιστρέφει σφάλμα/πληρεξούσιο.
503 Μη διαθέσιμη υπηρεσία - υποβάθμιση/προγραμματισμένη εργασία· προσθήκη 'Retry-After'.
Χρονοδιάγραμμα πύλης 504.
5) Σημασιολογία αναδρομής και ιδεατότητας
Δεν μπορείτε να αποσύρετε 400/ 401/403/404/422 (εκτός εάν ο πελάτης έχει αλλάξει το αίτημα).
Μπορείτε να ανασυρθείτε: 408/429/5xx/ 425/499/504 (με backoff + jitter).
Ταυτότητα: Για το 'POST', ενεργοποιήστε το 'Idempotency-Key' (UIDv4).
Για μια επανάληψη της σύγκρουσης, επιστρέψτε το 409 με το 'hint:' Χρησιμοποιήστε το ίδιο Idempotency-Key ή GET status ''.
Προσθήκη 'Idempotency-Replay: real' when returning a saved result.
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) Μερικές αποτυχίες (μερική/μερική ανεπάρκεια)
Στα τελικά σημεία παρτίδας, μην κρύβετε σφάλματα μέσα σε 200 χωρίς δομή. Επιστροφή 207 Multi-Status ή 200 με μια σειρά αποτελεσμάτων, όπου κάθε εργασία έχει το δικό της καθεστώς:json
{
"status": "partial",
"succeeded": 8,
"failed": 2,
"results": [
{"id": "op1", "status": 201},
{"id": "op2", "status": 422, "error": {"code":"VALIDATION_ERROR","detail":"..."}}
]
}
8) Πληκτρολόγηση και «κενές» απαντήσεις
Κενή συλλογή - αντικείμενα 200 s: [] ', όχι 404.
Το τέλος της σελίδας - 'next _ page _ token' λείπει.
Εσφαλμένη ένδειξη - κωδικός 400 s: PAGINATION_CURSOR_INVALID'.
9) Webhooks: Αξιόπιστη παράδοση
Υπογραφή γεγονότων (HMAC) και έλεγχος πριν από την επεξεργασία.
Η απόκριση στην επιτυχή επεξεργασία είναι 2xx (καλύτερη 204).
Προσωρινές αστοχίες δέκτη - 5xx. ο αποστολέας επαναλαμβάνει (εκθετική οπισθοδρόμηση, νευρικότητα).
Αφαίρεση από το 'event _ id' και εξοικονόμηση του αποτελέσματος (idempotent consumer).
Μη έγκυρο ωφέλιμο φορτίο - 400/422 καμία εγγραφή.
10) Συμμόρφωση με το πρωτόκολλο (gRPC/GraphQL)
gRPC → HTTP:- 'ΑΚΥΡΩΤΙΚΟ _ ΕΠΙΧΕΙΡΗΜΑ' → 400
- «ΜΗ ΕΓΚΕΚΡΙΜΕΝΕΣ» → 401
- 'ΑΔΕΙΑ _ ΑΠΟΡΡΙΦΘΗΚΕ' → 403
- 'NOT _ FOUND' → 404
- 'ΥΠΑΡΧΕΙ _ ΥΠΑΡΧΕΙ' → 409
- 'FAILED _ PREDITION' → 412/422
- «ΠΌΡΟς _ ΕΞΑΝΤΛΗΜΕΝΟΣ» → 429
- 'ΑΠΟΒΑΘΡΑ' → 409
- «ΜΗ ΔΙΑΘΈΣΙΜΟ» → 503
- 'ΠΡΟΘΕΣΜΙΑ _ ΥΠΕΡΒΑΣΗ' → 504
json
{
"data": { "createPayment": null },
"errors": [{
"message": "Forbidden",
"extensions": { "code": "FORBIDDEN", "status": 403, "trace_id": "..." },
"path": ["createPayment"]
}]
}
Συνιστάται να χρησιμοποιείται ο αντίστοιχος κωδικός HTTP αντί για 200 για κρίσιμα σφάλματα.
11) Τίτλοι και συμβουλές πελατών
'Retry-After' - δευτερόλεπτα/ημερομηνία HTTP (429/503/425/408).
'Προειδοποίηση' - απαλή υποβάθμιση ή υποβάθμιση («199 - Το χαρακτηριστικό Χ είναι καταθλιπτικό»).
"Απερήμωση", "Ηλιοβασίλεμα", "Σύνδεσμος: <...>, rel = «υποβάθμιση» '- για ελεγχόμενη παύση λειτουργίας.
'Τύπος προβλήματος' (προσαρμοσμένο) - γρήγορη δρομολόγηση σφαλμάτων στον πελάτη.
"X-Trace-I /" Συσχέτιση-Id" - συνδέσεις καταγραφής/ίχνη.
12) Ασφάλεια μηνυμάτων
Μην επαναλαμβάνετε μυστικά εισόδου (μάρκες/υπογραφές) στο σώμα απόκρισης.
Μάσκα PAN/PII ('1234').
Για 401/403 - να μην αποκαλυφθεί ποιο χαρακτηριστικό γνώρισμα απέτυχε.
Για 404, αντί για «πηγή υπάρχει αλλά όχι δική σας» - μόνο 404.
13) Παρατηρησιμότητα σφαλμάτων
Μετρήσεις:- 'http _ σφάλματα _ σύνολο {κατάσταση, διαδρομή, ενοικιαστής}'
- 'error _ classes _ total {code}' (by 'code' from the body)
- μοιράζονται 429, 5xx· 'p95 '/' p99' καθυστέρηση για εσφαλμένες απαντήσεις χωριστά
- 'retry _ after _ seconds _ bucket' - ιστόγραμμα συμβουλών επανάληψης
- συσχετίζει την απάντηση με "trace _ id", αποθηκεύει "code", "type", "status", "route", "renant", "no PII.
- ακίδα '5xx _ rate> X%' σε RPS> N;
- ανάπτυξη 429 σε κρίσιμες διαδρομές·
- 'timeout/504' των εξαρτήσεων,
- συχνή 409/idempotency → ένδειξη αγώνων.
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 in 'detail'.
Χρήση 'μηνύματος' αντί του σταθερού 'κωδικού '/' τύπου'.
Απόδοση 500 όταν συμβαίνει αναμενόμενο επιχειρηματικό σφάλμα (για παράδειγμα, «η ισορροπία είναι ανεπαρκής»).
Ασυνεπής σημασιολογία μεταξύ REST/GraphQL/gRPC.
16) Ιδιαιτερότητες του iGaming/Finance
Σαφείς κωδικοί για το KYC/AML/κυρώσεις: 'KYC _ REVIEW', 'AML _ LOCK', 'SANCTION _ BLOCKED'.
Περιορισμοί δικαιοδοσίας: 451 με ασφαλή διατύπωση χωρίς καταχώριση στον κατάλογο.
Πράξεις νομισματικής εγγραφής: 409/423 για τον ανταγωνισμό και τις κλειδαριές, «υπόδειξη» με ένα κόκκινο παράθυρο.
Περιορισμοί παικτών: Χρησιμοποιήστε το 422 για υπεύθυνες παραβιάσεις πληρωμών.
Έλεγχος: αμετάβλητα αρχεία καταγραφής λύσεων (κωδικός, χρόνος, φορέας, trace_id).
17) Κατάλογος ελέγχου ετοιμότητας Prod
- Ενιαίο σύστημα σφάλματος JSON, σταθερός «τύπος »/« κωδικός».
- Η χαρτογράφηση HTTP ↔ gRPC/GraphQL είναι συνεπής και τεκμηριωμένη.
- Retray σημασιολογία + 'Retry-After'; Ιδιαιτερότητα για γραφή.
- PII/μυστική κάλυψη? 404 για να κρύψει τους πόρους.
- Μετρήσεις σφάλματος και συναγερμού. συσχέτιση με το «trace _ id».
- Απορρίψτε τις πολιτικές: «Εξευτελισμός», «Ηλιοβασίλεμα», «Σύνδεσμος».
- Δοκιμές: αρνητική/fuzz, σύγκρουση έκδοσης, πτώση εξάρτησης, διπλή υποβολή.
- Οδηγός πελατών: Back-off παραδείγματα και 409/422/429/5xx επεξεργασία.
18) TL, DR
Τυποποιήστε μια ενιαία μορφή σφάλματος JSON με 'type '/' code '/' trace _ id', χρησιμοποιήστε τους σωστούς κωδικούς HTTP, διακρίνετε μεταξύ επικύρωσης (400/422), δικαιωμάτων (401/403/404), συγκρούσεων/ταυτότητας (409) και ορίων (429). Δώστε σαφή 'Retry-After' και 'int', μάσκα ευαίσθητων δεδομένων, καταγραφή σφαλμάτων με 'trace _ id' και κατασκευή ειδοποιήσεων με 5xx/429/p99.