Ana içeriğe geç

Hata Kodları

API isteklerinde karşılaşabileceğiniz hata kodları ve çözümleri.

HTTP Durum Kodları

HTTP Status Anlamı Ne Zaman Oluşur
200 OK Başarılı Health check endpoint'leri
202 Accepted Kabul edildi Sipariş başarıyla alındı
400 Bad Request Geçersiz istek JSON hatası, eksik alan
401 Unauthorized Yetkisiz Geçersiz kimlik bilgileri
403 Forbidden İzin yok Entegrasyon kapalı
404 Not Found Bulunamadı Geçersiz restaurant ID
409 Conflict Çakışma Duplicate order ID
422 Unprocessable Entity İşlenemez Validasyon hatası
429 Too Many Requests Çok fazla istek Rate limit aşıldı
500 Internal Server Error Sunucu hatası Beklenmeyen hata
503 Service Unavailable Servis kapalı Bakım modu

Hata Yanıt Formatı

Tüm hata yanıtları aşağıdaki formattadır:

{
  "error": "Human readable error message",
  "code": "ERROR_CODE",
  "details": {
    "field": "additionalInfo"
  }
}

Kimlik Doğrulama Hataları (401, 403)

AUTH_001: Invalid API Key

{
  "error": "Authentication failed",
  "code": "AUTH_001",
  "message": "Invalid API key"
}

Çözüm: API Key'inizi kontrol edin. MuditaKurye panelinden yeni bir key oluşturun.

AUTH_002: Expired API Key

{
  "error": "API key expired",
  "code": "AUTH_002"
}

Çözüm: API Key süresi dolmuş. Yeni bir key oluşturun ve sisteminizi güncelleyin.

AUTH_003: Invalid Basic Auth

{
  "error": "Authentication failed",
  "code": "AUTH_003",
  "message": "Invalid username or password"
}

Çözüm: Kullanıcı adı/şifre yanlış. Kimlik bilgilerinizi kontrol edin.

AUTH_004: Integration Disabled

{
  "error": "Third-party integration disabled",
  "code": "AUTH_004"
}

Çözüm: Restoran için entegrasyon kapatılmış. MuditaKurye panel → Ayarlar → Entegrasyon'dan etkinleştirin.

Validasyon Hataları (400, 422)

VAL_001: Missing Required Field

{
  "error": "Missing required field",
  "code": "VAL_001",
  "details": {
    "field": "orderId",
    "message": "orderId is required"
  }
}

Çözüm: orderId, restaurantId, customerName, deliveryAddress alanları zorunludur.

VAL_002: Invalid Field Format

{
  "error": "Validation error",
  "code": "VAL_002",
  "details": {
    "field": "customerPhone",
    "message": "Invalid phone number format",
    "expected": "E.164 format (e.g., +905551234567)"
  }
}

Çözüm: Alan formatını kontrol edin. Telefon numaraları E.164 formatında olmalı.

VAL_003: Invalid JSON

{
  "error": "Invalid JSON payload",
  "code": "VAL_003",
  "message": "Unexpected token } in JSON at position 123"
}

Çözüm: JSON syntax hatası var. JSON validator ile kontrol edin.

VAL_004: Payload Too Large

{
  "error": "Payload too large",
  "code": "VAL_004",
  "details": {
    "maxSize": "1 MB",
    "actualSize": "1.5 MB"
  }
}

Çözüm: İstek boyutu 1 MB'ı geçemez. items dizisini azaltın veya notes alanını kısaltın.

Kaynak Hataları (404, 409)

RES_001: Restaurant Not Found

{
  "error": "Restaurant not found",
  "code": "RES_001",
  "details": {
    "restaurantId": "rest_invalid123"
  }
}

Çözüm: restaurantId geçersiz. MuditaKurye panelinden doğru ID'yi kopyalayın.

RES_002: Duplicate Order ID

{
  "error": "Order already exists",
  "code": "RES_002",
  "details": {
    "orderId": "order_123456",
    "existingOrderStatus": "DELIVERED"
  }
}

Çözüm: Bu orderId daha önce kullanılmış. Her sipariş için benzersiz bir ID kullanın.

Rate Limiting (429)

RATE_001: Rate Limit Exceeded

{
  "error": "Rate limit exceeded",
  "code": "RATE_001",
  "details": {
    "limit": "100 requests per minute",
    "retryAfter": 45
  }
}

Çözüm: - retryAfter saniye bekleyin (header'da da Retry-After var) - İsteklerinizi batch'leyin - Daha yüksek limit için destek ekibiyle iletişime geçin

Best Practice:

async function createOrderWithRetry(orderData) {
  try {
    return await createOrder(orderData);
  } catch (error) {
    if (error.response?.status === 429) {
      const retryAfter = error.response.data.details?.retryAfter || 60;
      console.log(`Rate limited, waiting ${retryAfter} seconds...`);
      await sleep(retryAfter * 1000);
      return await createOrder(orderData); // Retry once
    }
    throw error;
  }
}

Sunucu Hataları (500, 503)

SRV_001: Internal Server Error

{
  "error": "Internal server error",
  "code": "SRV_001",
  "requestId": "req_abc123"
}

Çözüm: - requestId'yi kaydedin ve destek ekibine iletin - Kısa süre sonra tekrar deneyin - Hala devam ediyorsa destek ekibine bildirin

SRV_002: Service Unavailable

{
  "error": "Service temporarily unavailable",
  "code": "SRV_002",
  "message": "Scheduled maintenance in progress"
}

Çözüm: - Sistem bakımda veya geçici olarak kapalı - Bakım duyuruları için status.muditakurye.com kontrol edin - Exponential backoff ile tekrar deneyin

İş Mantığı Hataları

BIZ_001: Restaurant Closed

{
  "error": "Restaurant is closed",
  "code": "BIZ_001",
  "details": {
    "openingTime": "10:00",
    "closingTime": "22:00"
  }
}

Çözüm: Restoran şu anda kapalı. Çalışma saatleri dışında sipariş alınamaz.

BIZ_002: Delivery Area Not Supported

{
  "error": "Delivery address is outside service area",
  "code": "BIZ_002",
  "details": {
    "address": "...",
    "restaurantId": "rest_..."
  }
}

Çözüm: Teslimat adresi servis alanı dışında. Müşteriye farklı bir adres sorabilirsiniz.

BIZ_003: Minimum Order Amount

{
  "error": "Order total is below minimum",
  "code": "BIZ_003",
  "details": {
    "minimum": 50.00,
    "current": 35.00,
    "currency": "TRY"
  }
}

Çözüm: Minimum sipariş tutarı karşılanmamış. Müşteri daha fazla ürün eklemeli.

Hata İşleme Best Practices

1. Retry Stratejisi

const RETRY_CONFIG = {
  400: false,  // Client error - retry etme
  401: false,  // Auth error - retry etme
  404: false,  // Not found - retry etme
  409: false,  // Conflict - retry etme
  429: true,   // Rate limit - retry et
  500: true,   // Server error - retry et
  503: true    // Unavailable - retry et
};

async function createOrderWithRetry(orderData, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await createOrder(orderData);
    } catch (error) {
      const status = error.response?.status;
      const shouldRetry = RETRY_CONFIG[status];

      if (!shouldRetry || i === maxRetries - 1) {
        throw error;
      }

      // Exponential backoff: 1s, 2s, 4s
      const delay = Math.pow(2, i) * 1000;
      console.log(`Retry ${i + 1}/${maxRetries} after ${delay}ms`);
      await sleep(delay);
    }
  }
}

2. Error Loglama

function logApiError(error, context) {
  const errorDetails = {
    timestamp: new Date().toISOString(),
    context,
    status: error.response?.status,
    code: error.response?.data?.code,
    message: error.response?.data?.error,
    requestId: error.response?.headers?.['x-request-id'],
    requestData: error.config?.data,
    stack: error.stack
  };

  console.error('API Error:', JSON.stringify(errorDetails, null, 2));

  // Monitoring servisine gönder (örn: Sentry, DataDog)
  if (process.env.NODE_ENV === 'production') {
    monitoring.captureException(error, errorDetails);
  }
}

3. User-Friendly Messages

API hata mesajlarını kullanıcı dostu mesajlara dönüştürün:

const ERROR_MESSAGES = {
  'AUTH_001': 'Sistem bağlantı hatası. Lütfen tekrar deneyin.',
  'RES_001': 'Restoran bilgisi bulunamadı. Destek ekibiyle iletişime geçin.',
  'BIZ_002': 'Bu adrese teslimat yapılamıyor. Lütfen başka bir adres deneyin.',
  'RATE_001': 'Çok fazla istek gönderildi. Lütfen biraz bekleyin.',
  'VAL_002': 'Telefon numarası geçersiz. Lütfen kontrol edin.',
  // ...
};

function getUserFriendlyMessage(errorCode) {
  return ERROR_MESSAGES[errorCode] || 'Bir hata oluştu. Lütfen tekrar deneyin.';
}

İzleme ve Alerting

Metrics to Track

Metric Threshold Action
Error Rate > 5% Alert on-call engineer
401/403 Errors > 10/hour Check API key rotation
500 Errors > 0 Immediate investigation
429 Rate Limits > 50/day Increase limit or batch requests
Avg Response Time > 2s Performance optimization

Health Check Monitoring

Periyodik olarak health check endpoint'ini kontrol edin:

const cron = require('node-cron');

// Her 5 dakikada bir health check
cron.schedule('*/5 * * * *', async () => {
  try {
    const response = await axios.get(
      'https://api.muditakurye.com.tr/webhook/third-party/health',
      { timeout: 5000 }
    );

    if (response.status !== 200) {
      alertOps(`MuditaKurye API health check failed: ${response.status}`);
    }
  } catch (error) {
    alertOps(`MuditaKurye API is down: ${error.message}`);
  }
});

Destek

Çözülemeyen hatalar için:

Sonraki Adım

Kod örnekleri için Örnekler sayfasına geçin.