ReferansHata Kodları

Hata Kodları

HummyTummy API’sindeki tüm hatalar tek bir standart hata zarfı ile döner. İstemci tarafında metin mesajına göre değil, kararlı errorCode alanına göre dallanmanız önerilir.

Hata zarfı

Her hata yanıtı aşağıdaki yapıyı izler:

{
  "statusCode": 409,
  "message": "User with email '[email protected]' already exists",
  "error": "RESOURCE_ALREADY_EXISTS",
  "errorCode": "RESOURCE_ALREADY_EXISTS",
  "timestamp": "2026-06-23T08:14:05.123Z",
  "path": "/api/v1/auth/register",
  "requestId": "1750665245123-a1b2c3d4e"
}
AlanTipAçıklama
statusCodenumberHTTP durum kodu.
messagestring | string[]Kullanıcıya gösterilebilir mesaj. Doğrulama hatalarında bir dizi olabilir.
errorstringİnsan/kategori etiketi (bazen yerelleştirilmiş ya da class-validator’ın "Bad Request" değeri). Buna göre dallanmayın.
errorCodestring?Kararlı, makine-okunur kod. İstemci yalnızca buna göre dallanmalıdır. Yalnızca fırlatılan istisna bir kod iliştirdiğinde bulunur.
timestampstringİstek zaman damgası (ISO 8601).
pathstringİstek yolu.
requestIdstring?İzleme için istek kimliği — destek talebinde paylaşın.
actionableobject?Yapılandırılmış remediation yükü. Bugün yetki reddini taşır: requirement, offer, licenseRequired, reason.
detailsany?Yalnızca development ortamında bulunur.
stackstring?Yalnızca development ortamında bulunur.

errorCode PII içermez ve bu nedenle her ortamda (production dahil) döner. details ve stack ise yalnızca development ortamında yer alır.

⚠️

error alanı yerelleştirilebilir veya çerçevenin ürettiği bir etikete düşebilir. Davranışsal dallanmayı her zaman errorCode üzerinden yapın; errorCode yoksa statusCode’a düşün.

errorCode değerleri

Aşağıdaki kodlar ErrorCode enum’ından gelir ve iş mantığı istisnalarıyla (BusinessException) iliştirilir.

Bazı kapılar (yetki guard’ı, satın alınabilirlik kapısı, stok kapısı) kendi kodlarını code alanıyla fırlatır; global hata filtresi bunları errorCode’a standardize eder. Yani istemci tek bir alana bakar. Bu kodlar aşağıda Yetki ve satın alma başlığında.

Kimlik doğrulama

errorCodeAnlamı
INVALID_CREDENTIALSE-posta veya parola hatalı.
TOKEN_EXPIREDToken’ın süresi doldu.
TOKEN_INVALIDToken geçersiz/bozuk.
UNAUTHORIZEDKimlik doğrulama gerekli.

Yetkilendirme

errorCodeAnlamı
FORBIDDENErişim reddedildi.
INSUFFICIENT_PERMISSIONSRol/izin bu işlem için yetersiz.

Kaynak

errorCodeAnlamı
RESOURCE_NOT_FOUNDİstenen kayıt yok.
RESOURCE_ALREADY_EXISTSAynı kayıt zaten var (ör. yinelenen e-posta).
RESOURCE_CONFLICTKaynağın mevcut durumuyla çakışma.

Doğrulama

errorCodeAnlamı
VALIDATION_ERRORGenel girdi doğrulaması başarısız.
INVALID_INPUTGirdi değeri geçersiz.
MISSING_REQUIRED_FIELDZorunlu alan eksik.

İş mantığı

errorCodeAnlamı
INSUFFICIENT_STOCKÜrün için yeterli stok yok. details: { productName, available, requested }.
ORDER_ALREADY_PAIDSipariş zaten ödenmiş.
TABLE_OCCUPIEDMasa dolu.
INVALID_ORDER_STATUSİşlem siparişin mevcut durumunda yapılamaz.
QUOTA_EXCEEDEDKontör bakiyesi yetersiz (HTTP 402). details: { kind, remaining, requested, offerCode }offerCode, istemcinin doğrudan derin bağ verebileceği kontör paketidir.
SUBSCRIPTION_REQUIREDDevre dışı. Plan rayıyla birlikte emekliye ayrıldı; hiçbir kod yolu artık bunu fırlatmıyor. Enum’da yalnızca eski istemciler kırılmasın diye duruyor.
FEATURE_NOT_AVAILABLEDevre dışı. Yerine ENTITLEMENT_REQUIRED (HTTP 403) döner — o zarf eksik yetkiyi ve onu açan ürünü fiyatıyla taşır.

Ödeme

errorCodeAnlamı
PAYMENT_FAILEDÖdeme başarısız oldu.
PAYMENT_PROCESSING_ERRORÖdeme işlenirken hata.
INVALID_PAYMENT_METHODGeçersiz ödeme yöntemi.

Sistem

errorCodeAnlamı
INTERNAL_SERVER_ERRORBeklenmeyen sunucu hatası.
SERVICE_UNAVAILABLEServis geçici olarak kullanılamıyor.
DATABASE_ERRORVeritabanı hatası.
EXTERNAL_SERVICE_ERRORDış servis hatası (ör. ödeme sağlayıcı).

Hız sınırı

errorCodeAnlamı
TOO_MANY_REQUESTSÇok fazla istek (HTTP 429).

Tenant

errorCodeAnlamı
TENANT_NOT_FOUNDTenant bulunamadı.
INVALID_TENANTGeçersiz tenant.

Yetki ve satın alma

Bu kodlar ErrorCode enum’ında değildir; ilgili kapılar code alanıyla fırlatır, global filtre de bunu errorCode’a taşır — istemci yine tek alana bakar.

errorCodeHTTPAnlamı
ENTITLEMENT_REQUIRED403Rota bir yetki istiyor ve tenant’ta yok. actionable içinde requirement, offer, licenseRequired, reason gelir.
LICENSE_REQUIRED409Sepetteki ürün lisans ister; ne sahiplikte ne sepette lisans var.
ADDON_ALREADY_OWNED409Ürün (ya da lisans) zaten aktif.
ADDON_ALREADY_GRANTED409Ürünün verdiği her şey zaten yetki setinde.
ADDON_REQUIRES_DEPENDENCY409Bağımlı olduğu ürün ne sahiplikte ne sepette.
ADDON_LIMIT_REDUNDANT409Eklediği kapasite zaten sınırsız.
ADDON_MAX_QUANTITY409Katalog adet tavanı aşılıyor.
HARDWARE_OUT_OF_STOCK409Donanım satırı için yeterli gerçek stok yok.
CATALOG_INVALID400Süperadmin katalog yazımı ürün değişmezlerini ihlal ediyor; message tüm sorunları dizi olarak taşır.

409 kodlarının tamamı tahsilattan önce, POST /v1/checkout/intent içinde döner: reddedilen satır sepetin tamamını durdurur, CheckoutIntent satırı yazılmaz ve PayTR hiç çağrılmaz. Ayrıntılar için Lisans & Ödeme API ve Yetki Matrisi.

Veritabanı hatalarının HTTP eşlemesi

Prisma’nın bilinen veritabanı hataları (PrismaClientKnownRequestError) global istisna filtresinde anlamlı HTTP durum kodlarına çevrilir. Bu yanıtlarda error alanı kategori etiketini taşır; errorCode bu durumlarda bulunmaz (bunlar BusinessException değildir).

Prisma koduHTTPerrorAnlamı
P2002409 ConflictUniqueConstraintViolationTekil kısıt ihlali (yinelenen kayıt).
P2025404 Not FoundRecordNotFoundKayıt bulunamadı.
P2003400 Bad RequestForeignKeyConstraintViolationİlişkili kayıt yok veya bağımlılık nedeniyle silinemiyor.
P2014400 Bad RequestRequiredRelationViolationDeğişiklik zorunlu bir ilişkiyi ihlal ederdi.
P2016400 Bad RequestInvalidQueryGeçersiz sorgu parametreleri.
P2021500 Internal Server ErrorDatabaseConfigErrorTablo yok (yapılandırma hatası).
P2024503 Service UnavailableDatabaseTimeoutVeritabanı bağlantı zaman aşımı.
P2034409 ConflictConcurrentUpdateSerileştirilebilir işlem çakışması (Postgres 40001). İşlem commit olmadı, güvenle yeniden denenebilir.
P2000, P2020400 Bad RequestValueOutOfRangeDeğer izin verilen aralık dışı veya çok uzun.
(diğer)500 Internal Server ErrorDatabaseErrorEşlenmemiş veritabanı hatası.

P2034 (ConcurrentUpdate, 409) ödeme uzlaştırma, marketplace satın alma gibi yarış durumu altındaki Serializable işlemlerin beklenen “kaybeden” sonucudur ve isteğiniz hiç işlenmemiştir. Bu yanıtı alırsanız isteği aynen yeniden gönderebilirsiniz.

İstemci tarafında işleme

const res = await fetch('/api/v1/display/orders', { method: 'POST', /* … */ });
if (!res.ok) {
  const err = await res.json(); // ErrorResponse
  switch (err.errorCode) {
    case 'ENTITLEMENT_REQUIRED': {
      // 403 — err.actionable.offer, eksik yetkiyi açan ürünü BU tenant için
      // bugünkü fiyatıyla taşır. reason === 'lapsed' → "Yenile", aksi → "Satın al".
      const { offer, reason, licenseRequired } = err.actionable ?? {};
      showPurchasePrompt({ offer, reason, licenseRequired });
      break;
    }
    case 'QUOTA_EXCEEDED':
      // 402 — kontör bitti. err.details.offerCode ile kontör paketine derin bağ ver.
      break;
    case 'LICENSE_REQUIRED':
    case 'ADDON_ALREADY_OWNED':
    case 'ADDON_ALREADY_GRANTED':
    case 'ADDON_REQUIRES_DEPENDENCY':
    case 'ADDON_LIMIT_REDUNDANT':
    case 'ADDON_MAX_QUANTITY':
      // 409 — sepet düzeltilmeli; hiçbir tahsilat yapılmadı.
      showToast(err.message);
      break;
    case undefined:
      // errorCode yok → statusCode'a göre dallan (ör. 409 ConcurrentUpdate → retry)
      break;
    default:
      showToast(err.message);
  }
}