Errors
Error envelope şekli, tam error code kataloğu, retry semantiği ve rate-limit'e özgü işleme.
Her Moonborn error response'u aynı envelope'u paylaşır:
{
"error": {
"code": "rate_limited",
"message": "Per-minute API rate limit exceeded.",
"details": { "retryAfter": 12 }
}
}code stable, machine-readable bir string. message human-readable
(log'larda göstermek güvenli; çeviri yapmadan end user'a gösterme).
details ilgili olduğunda koda özgü alanlar taşır.
HTTP status code mapping
| Status | Ne zaman |
|---|---|
400 | bozuk istek (parse hatası, eksik zorunlu alan) |
401 | eksik ya da geçersiz bearer token |
403 | authenticated ama unauthorized (scope ya da role yetersiz) |
404 | resource bulunamadı |
409 | conflict — tipik olarak idempotency key collision, drift block ya da persona state machine reddi |
422 | validation hatası (şekil geçerli, semantik değil) |
429 | rate-limited |
500 | beklenmedik sunucu hatası |
502/503/504 | upstream LLM provider sorunu; retry |
Error code kataloğu
| Code | Status | Anlam |
|---|---|---|
unauthorized | 401 | Bearer token eksik ya da expired |
forbidden | 403 | Token geçerli, scope/role yetersiz |
not_found | 404 | Resource yok ya da caller'a görünür değil |
validation_failed | 422 | Request body şekli geçerli ama değer aralığı / enum / zorunlu-alan uyumsuzluğu |
idempotency_conflict | 409 | Aynı idempotency key, farklı payload |
state_conflict | 409 | Resource state machine geçişi reddetti (örn. zaten silinmiş bir personayı archive etmek) |
drift_blocked | 409 | Drift detection action=block bu yanıtta tetiklendi |
audit_blocked | 409 | Audit verdict'i eşik altında; persona flagged state'inde döndü |
moderation_blocked | 422 | Output moderasyondan kaldı; yanıt reddedildi |
rate_limited | 429 | Tier başı rate cap'i vuruldu; details.retryAfter (saniye) cooldown'ı taşır |
quota_exceeded | 429 | Aylık kota vuruldu (örn. generation kotası) |
provider_error | 502 | Upstream LLM provider hatası; backoff ile retry |
provider_timeout | 504 | Upstream LLM provider timeout |
internal_error | 500 | Handle edilmemiş exception; bizde loglandı |
Retry semantiği
SDK'lar bu kodları exponential backoff ile auto-retry yapar:
provider_error(5xx)provider_timeout(504)rate_limited(429) —Retry-Afterheader'ına uyar
Bu kodlar asla auto-retry edilmez:
validation_failed— önce request'i düzeltidempotency_conflict— key'i değiştirdrift_blocked/audit_blocked/moderation_blocked— caller kararı
Idempotency-Key
Her write request bir Idempotency-Key header'ı kabul eder. 24 saat
içindeki replay'ler orijinal yanıtı döndürür. SDK'lar default'ta
key'i auto-generate eder; deterministik bir business key'in varsa
çağrı başı override et (Idempotency-Key: order-12345).
Rate-limit header'ları
Her response (başarı ya da error) taşır:
X-RateLimit-Limit: 3000
X-RateLimit-Remaining: 2987
X-RateLimit-Reset: 1747498200
Client'ında backpressure için X-RateLimit-Remaining kullan. Tier
başı cap'ler için Rate limits'e bak.
Dürüst kapsam
Yukarıdaki kodları izleriz; internal exception tip'leri, stack
trace'leri ya da upstream provider error code'larını yüzeye
çıkarmayız. Bir provider_error'ı debug ediyorsan, audit log
(GET /v1/audit/events) details altında upstream error envelope'u
taşır.