GH GambleHub

API коди помилок і best practices

1) Навіщо стандартизувати помилки

Передбачуваність для клієнтів: єдиний формат і поведінка ретраїв.
Прискорення дебагу: 'trace _ id '/' request _ id', стабільні'error _ code'.
Безпека: не витечуть SQL/stack traces/конфіги.
Спостережуваність: звітність з таксономії помилок (валідація, квоти, таймаути тощо).

2) Базові принципи

1. Єдиний формат відповіді для всіх 4xx/5xx (і для 2xx з частковими помилками - окрема схема).
2. Чітка семантика HTTP: вірний статус найважливіше.
3. Два рівні коду: транспортний ('status') і доменний стабільний'error _ code'.
4. Retriable vs Non-retriable: вказуйте явно і давайте підказку по бек-оффу.
5. Типова безпека: подробиці - тільки клієнту з правами; без внутрішніх трас.
6. Локалізація: машинний код залишається стабільним, текст - перекладаємо.

3) Єдиний формат помилки (на базі RFC 7807)

Рекомендований JSON (розширений'application/problem + json'):
json
{
"type": "https://api. example. com/errors/validation_failed",
"title": "Validation failed",
"status": 422,
"error_code": "VAL_001",
"detail": "Field 'email' must be a valid address",
"instance": "req_01HZY...93",
"trace_id": "a1b2c3d4e5f6",
"retriable": false,
"errors": [
{"field": "email", "code": "email_invalid", "message": "Invalid email"}
],
"hint": "Fix payload and retry",
"meta": {"docs": "https://docs. example. com/errors#VAL_001"}
}

Обов'язкові: `type`, `title`, `status`, `error_code`, `trace_id`.
Опціонально: «errors []» (по полях), «retriable», «hint», «meta».

Заголовки у відповіді:
  • `Content-Type: application/problem+json`
  • `X-Request-ID`/`Traceparent` (W3C)
  • (для 429/503)'Retry-After'( секунди або дата)

4) Семантика HTTP статусів (злиття «класики» і практики)

2xx (успіх з нюансами)

200 OK - звичайний успіх.
201 Created - створено ресурс (Location).
202 Accepted - асинхронно в черзі (дайте'status _ url').
207 Multi-Status - частковий успіх (уникайте, якщо можна).

4xx (помилка клієнта)

400 Bad Request - синтаксис/формат, але не валідація полів (краще 422).
401 Unauthorized - ні/невірний токен. Давайте'WWW-Authenticate'.
403 Forbidden - токен валіден, але прав не вистачає (RBAC/ABAC/ліміти).
404 Not Found - ресурс/ендпоінт відсутній.
409 Conflict - конфлікт версій/стану (optimistic locking, idempotency).
410 Gone - ендпоінт назавжди прибраний.
412 Precondition Failed - ETag/If-Match не пройшов.
415 Unsupported Media Type - неправильний'Content-Type'.
422 Unprocessable Entity - валідація бізнес-правил.
429 Too Many Requests - перевищені квоти/швидкість (див. § 7).

5xx (помилка сервера)

500 Internal Server Error - раптова помилка; не розголошувати деталі.
502 Bad Gateway - помилка апстріму.
503 Service Unavailable - деградація/перевантаження, дайте'Retry-After'.
504 Gateway Timeout - таймаут бекенду.

💡 Поріг: 4xx не ретраїмо, 5xx можна ретраїти (з backoff/jitter), 429 - ретрай після'Retry-After'.

5) Таксономія доменних'error _ code '

Рекомендуємо діапазони:
  • 'AUTH _'- автентифікація/авторизація.
  • 'VAL _'- валідація вхідних даних.
  • 'RATELIMIT _'- квоти і швидкість.
  • 'IDEMP _'- ідемпотентність/дублікати.
  • 'CONFLICT _'- версії/стан.
  • 'DEP _'- залежності (PSP/DNS/SMTP).
  • 'PAY _'- бізнес-помилки платіжного домену.
  • 'SEC _'- безпека (підписи, HMAC, mTLS).
  • 'INT _'- внутрішні раптові.
Вимоги:
  • Стабільність у часі (back-compat).
  • Описи та приклади в каталозі помилок (docs + machine-readable JSON).

6) Retriable vs Non-retriable

Поля:
  • `retriable: true|false`
  • Якщо'true'- обов'язково'Retry-After'( в секундах) або контракт «експоненціальний бек-офф (починаючи з 1-2 с, макс 30-60 с)».

Retriable зазвичай: '502/503/504', деякі'500','429'( після вікна).
Non-retriable: `400/401/403/404/409/410/415/422`.

7) Rate limit & quota помилки (429)

Тіло:
json
{
"type": "https://api. example. com/errors/rate_limited",
"title": "Rate limit exceeded",
"status": 429,
"error_code": "RATELIMIT_RPS",
"detail": "Too many requests",
"retriable": true
}
Заголовки:
  • `Retry-After: 12`
  • `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`
  • Для квот: `X-Quota-Limit`, `X-Quota-Remaining`, `X-Quota-Reset`

8) Ідемпотентність і конфлікти

У запитах на запис -'Idempotency-Key'( унікальний в межах 24-72 год).
Конфлікт повторної операції → 409 Conflict з'error _ code: "IDEMP_REPLAY"`.
Конфлікт версій ресурсу по ETag → 412 Precondition Failed.
У відповіді додайте'resource _ id '/' status _ url'для безпечного повторного запиту.

9) Валідація і 422

Повертайте список помилок по полях:
json
{
"status": 422,
"error_code": "VAL_001",
"errors": [
{"field":"email","code":"email_invalid","message":"Invalid email"},
{"field":"age","code":"min","message":"Must be >= 18"}
]
}
Правила:
  • Не дублюйте те ж в 400 - 422 краще для бізнес-валідації.
  • Повідомлення - людиночитані;'code'- машинний.

10) Безпека помилок

Ніколи: stack traces, SQL, шляхи файлів, приватні імена хостів.
Редагуйте PII; слідкуйте за GDPR/DSAR.
Для підпису/НМАС: розрізняйте'SEC _ SIGNATURE _ MISMATCH'( 403) і'SEC _ TIMESTAMP _ SKEW'( 401/403) з підказкою «перевірте час ± 5 хв».

11) Кореляція і спостережуваність

Завжди додавайте'trace _ id '/' X-Request-ID'і прокидайте в логи/траси.
Помилки агрегуйте по'error _ code'і'status'→ дашборди «топ-помилки», «new vs known».
Алерти: сплеск 5xx/422/429, латентність p95, share of errors.

12) gRPC/GraphQL/Webhooks - маппінги

gRPC ↔ HTTP

gRPCЗначенняHTTP
`OK`успіх200
`INVALID_ARGUMENT`Валідація422/400
`UNAUTHENTICATED`немає токена401
`PERMISSION_DENIED`немає прав403
`NOT_FOUND`немає ресурсу404
`ALREADY_EXISTS`конфлікт409
`FAILED_PRECONDITION`ETag/передумови412
`RESOURCE_EXHAUSTED`квоти429
`UNAVAILABLE`недоступно503
`DEADLINE_EXCEEDED`Таймаут504
`INTERNAL`внутрішня500

GraphQL

Транспорт 200, але'errors []'всередині - додавайте'extensions. code` и `trace_id`.
Для «фатала» (автентифікація/квоти) - краще реальний HTTP 401/403/429.

Webhooks

Вважайте успішним тільки 2xx одержувача.
Ретраї з експоненціальним бек-оффом,'X-Webhook-ID','X-Signature'.
410 від одержувача - зупинити ретраї (endpoint видалений).

13) Версіонування помилок

'type '/' error _ code'- стабільні; нові - тільки додавати.
При зміні схеми тіла - підвищуйте мінорну версію API або'problem + json; v=2`.
Документація: таблиця кодів + приклади; changelog помилок.

14) Документація (OpenAPI фрагменти)

Глобальні відповіді

yaml components:
responses:
Problem:
description: Problem Details content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
schemas:
Problem:
type: object required: [type, title, status, error_code, trace_id]
properties:
type: { type: string, format: uri }
title: { type: string }
status: { type: integer }
error_code: { type: string }
detail: { type: string }
instance: { type: string }
trace_id: { type: string }
retriable: { type: boolean }
errors:
type: array items:
type: object properties:
field: { type: string }
code: { type: string }
message: { type: string }

Приклад ендпоінта

yaml paths:
/v1/users:
post:
responses:
'201': { description: Created }
'401': { $ref: '#/components/responses/Problem' }
'422': { $ref: '#/components/responses/Problem' }
'429': { $ref: '#/components/responses/Problem' }
'500': { $ref: '#/components/responses/Problem' }

15) Тестування та якість

Контракт-тести: відповідність'application/problem + json', обов'язкові поля.
Negative tests: всі гілки 401/403/404/ 409/422/429/500.
Chaos/latency: перевірка ретраїв на 5xx/ 503/504/429 («Retry-After»).
Security tests: відсутність внутрішніх повідомлень, коректна маска PII.
Backward-compat: старі клієнти розуміють нові поля (додавайте, не ламайте).

16) Чек-лист впровадження

  • Єдиний'problem + json'+ стабільні'error _ code'.
  • Коректна семантика HTTP/гRPC/GraphQL.
  • Retriable/non-retriable +'Retry-After '/рекомендації бек-оффа.
  • Rate-limit заголовки і 429 поведінка.

Ідемпотентність («Idempotency-Key», 409/412).

  • Безпека: без stack traces/секретів, PII-редакція.
  • 'trace _ id '/' X-Request-ID'у всіх помилках.
  • Документація каталогу помилок і приклади.
  • Моніторинг з таксономії помилок.
  • Автотести негативних сценаріїв.

17) Міні-FAQ

Чим 400 відрізняється від 422?
400 - зламаний запит (синтаксис/тип вмісту). 422 - валідний за синтаксисом, але бізнес-правила не пройшли.

Коли 401, а коли 403?
401 - ні/невірний токен; 403 - токен є, прав не вистачає.

Чи потрібен завжди'Retry-After'?
Для 429/503 - так; для решти retriable - бажано давати явну рекомендацію.

Підсумок

Добре спроектовані помилки - це контракт: коректний HTTP-статус, єдиний'problem + json', стабільні'error _ code', явні підказки по ретраях і сувора безпека. Стандартизуйте формат, документуйте таксономію, додайте телеметрію і тести - і ваш API стане передбачуваним, безпечним і доброзичливим до інтеграторів.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Telegram
@Gamble_GC
Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.