> ## Documentation Index
> Fetch the complete documentation index at: https://dkkangoyazlmteknolojiticareta.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> Handle API errors gracefully in your integration

## Error Response Format

All errors follow this standard structure:

```json theme={null}
{
  "status": false,
  "error": "error_code",
  "message": "Detailed error message"
}
```

## Common Error Codes

| HTTP Status | Error Code            | Description                  | How to Handle                      |
| ----------- | --------------------- | ---------------------------- | ---------------------------------- |
| 400         | eksik alan            | Missing required field       | Check request body                 |
| 401         | yetkisiz erişim       | Invalid/expired token        | Refresh access token               |
| 403         | URL hatalı            | Invalid UUID or unauthorized | Verify resource ID and permissions |
| 404         | sipariş bulunamadı    | Order not found              | Order may have been deleted        |
| 404         | restoran bulunamadı   | Restaurant not found         | Check restaurant ID                |
| 404         | ürün bulunamadı       | Food item not found          | Check food ID                      |
| 422         | eksik alan            | Malformed request            | Validate request format            |
| 429         | çok fazla istek       | Rate limit exceeded          | Wait 30 seconds before retry       |
| 500         | Internal server error | Server error                 | Retry with exponential backoff     |

## Error Handling Strategy

<Steps>
  <Step title="Catch All Errors">
    Always wrap API calls in try-catch blocks
  </Step>

  <Step title="Parse Error Response">
    Extract error code and message from response
  </Step>

  <Step title="Handle Specific Errors">
    Implement specific handling for each error type
  </Step>

  <Step title="Log for Debugging">
    Log errors with context for troubleshooting
  </Step>

  <Step title="Notify User">
    Display user-friendly error messages
  </Step>
</Steps>

## Implementation Example

```javascript theme={null}
class APIError extends Error {
  constructor(status, errorCode, message) {
    super(message);
    this.status = status;
    this.errorCode = errorCode;
    this.name = 'APIError';
  }
}

async function makeApiCall(endpoint, options = {}) {
  try {
    const response = await fetch(endpoint, options);
    const data = await response.json();
    
    if (!data.status) {
      throw new APIError(
        response.status,
        data.error,
        data.message || data.error
      );
    }
    
    return data.data;
    
  } catch (error) {
    // Handle network errors
    if (error instanceof TypeError) {
      throw new APIError(0, 'network_error', 'Unable to connect to API');
    }
    
    throw error;
  }
}

async function handleApiCall(apiFunction) {
  try {
    return await apiFunction();
  } catch (error) {
    if (error instanceof APIError) {
      return handleAPIError(error);
    } else {
      console.error('Unexpected error:', error);
      throw error;
    }
  }
}

function handleAPIError(error) {
  switch (error.status) {
    case 401:
      return handleAuthError(error);
    
    case 403:
      return handleForbiddenError(error);
    
    case 404:
      return handleNotFoundError(error);
    
    case 422:
      return handleValidationError(error);
    
    case 429:
      return handleRateLimitError(error);
    
    case 500:
      return handleServerError(error);
    
    default:
      return handleGenericError(error);
  }
}
```

## Handling Specific Errors

<Tabs>
  <Tab title="401 - Authentication">
    ```javascript theme={null}
    async function handleAuthError(error) {
      console.log('Token expired or invalid');
      
      // 1. Try to refresh token
      try {
        await refreshAccessToken();
        
        // 2. Retry the failed request
        return await retryLastRequest();
        
      } catch (refreshError) {
        // 3. If refresh fails, redirect to login
        redirectToLogin();
        throw new Error('Authentication failed');
      }
    }

    async function refreshAccessToken() {
      const credentials = getStoredCredentials();
      
      const response = await login(
        credentials.appSecret,
        credentials.restSecret
      );
      
      storeAccessToken(response.access_token);
      return response;
    }
    ```
  </Tab>

  <Tab title="403 - Forbidden">
    ```javascript theme={null}
    function handleForbiddenError(error) {
      if (error.errorCode === 'URL hatalı') {
        // Invalid UUID or resource ID
        console.error('Invalid resource ID');
        notifyUser('The requested resource ID is invalid');
        
        // Log for debugging
        logError('Invalid UUID', {
          endpoint: error.endpoint,
          resourceId: error.resourceId
        });
        
      } else {
        // Insufficient permissions
        console.error('Access denied');
        notifyUser('You do not have permission to access this resource');
      }
    }
    ```
  </Tab>

  <Tab title="404 - Not Found">
    ```javascript theme={null}
    function handleNotFoundError(error) {
      switch (error.errorCode) {
        case 'sipariş bulunamadı':
          console.log('Order not found');
          notifyUser('Order not found. It may have been canceled.');
          break;
        
        case 'restoran bulunamadı':
          console.log('Restaurant not found');
          notifyUser('Restaurant not found');
          break;
        
        case 'ürün bulunamadı':
          console.log('Food item not found');
          notifyUser('Menu item not found');
          break;
        
        default:
          notifyUser('The requested resource was not found');
      }
    }
    ```
  </Tab>

  <Tab title="422 - Validation">
    ```javascript theme={null}
    function handleValidationError(error) {
      console.error('Validation failed:', error.message);
      
      // Extract field name from error message
      const fieldMatch = error.message.match(/(\w+) is required/);
      const fieldName = fieldMatch ? fieldMatch[1] : 'unknown';
      
      // Highlight error in UI
      highlightErrorField(fieldName);
      
      // Show user-friendly message
      notifyUser(`Please provide a valid ${fieldName}`);
      
      // Log for debugging
      logValidationError({
        field: fieldName,
        message: error.message,
        requestData: error.requestData
      });
    }
    ```
  </Tab>

  <Tab title="429 - Rate Limit">
    ```javascript theme={null}
    async function handleRateLimitError(error) {
      console.log('Rate limit exceeded');
      
      // Show user message
      notifyUser('Too many requests. Please wait 30 seconds.');
      
      // Wait 30 seconds
      await sleep(30000);
      
      // Retry automatically
      console.log('Retrying request...');
      return await retryLastRequest();
    }

    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    ```
  </Tab>

  <Tab title="500 - Server Error">
    ```javascript theme={null}
    async function handleServerError(error, attempt = 1) {
      const maxRetries = 3;
      
      console.error(`Server error (attempt ${attempt}/${maxRetries})`);
      
      if (attempt >= maxRetries) {
        // Give up after max retries
        notifyUser('Server error. Please try again later.');
        logCriticalError('Server error after max retries', error);
        throw error;
      }
      
      // Exponential backoff: 1s, 2s, 4s
      const delay = 1000 * Math.pow(2, attempt - 1);
      console.log(`Waiting ${delay}ms before retry...`);
      await sleep(delay);
      
      // Retry
      try {
        return await retryLastRequest();
      } catch (retryError) {
        return handleServerError(retryError, attempt + 1);
      }
    }
    ```
  </Tab>
</Tabs>

## Retry Strategy

```javascript theme={null}
class RetryHandler {
  constructor(maxRetries = 3) {
    this.maxRetries = maxRetries;
    this.retryableErrors = [429, 500, 502, 503, 504];
  }
  
  async execute(apiFunction, attempt = 1) {
    try {
      return await apiFunction();
      
    } catch (error) {
      // Check if error is retryable
      if (!this.shouldRetry(error, attempt)) {
        throw error;
      }
      
      // Calculate delay with exponential backoff
      const delay = this.calculateDelay(error, attempt);
      
      console.log(`Retry attempt ${attempt}/${this.maxRetries} in ${delay}ms`);
      await sleep(delay);
      
      // Retry
      return this.execute(apiFunction, attempt + 1);
    }
  }
  
  shouldRetry(error, attempt) {
    if (attempt >= this.maxRetries) {
      return false;
    }
    
    if (error instanceof APIError) {
      return this.retryableErrors.includes(error.status);
    }
    
    // Retry network errors
    return error instanceof TypeError;
  }
  
  calculateDelay(error, attempt) {
    // Rate limit: wait full 30 seconds
    if (error.status === 429) {
      return 30000;
    }
    
    // Exponential backoff for other errors: 1s, 2s, 4s
    return 1000 * Math.pow(2, attempt - 1);
  }
}

// Usage
const retryHandler = new RetryHandler(3);

try {
  const orders = await retryHandler.execute(() => 
    getOrders()
  );
} catch (error) {
  console.error('Failed after retries:', error);
}
```

## Logging Best Practices

```javascript theme={null}
class ErrorLogger {
  log(error, context = {}) {
    const logEntry = {
      timestamp: new Date().toISOString(),
      error: {
        name: error.name,
        message: error.message,
        stack: error.stack,
        status: error.status,
        errorCode: error.errorCode
      },
      context: {
        ...context,
        userId: currentUser?.id,
        restaurantId: currentRestaurant?.id,
        endpoint: context.endpoint,
        requestData: context.requestData
      },
      environment: process.env.NODE_ENV,
      version: APP_VERSION
    };
    
    // Log to console
    console.error('API Error:', logEntry);
    
    // Send to error tracking service
    if (errorTracker) {
      errorTracker.captureException(error, logEntry);
    }
    
    // Store locally for debugging
    this.storeLog(logEntry);
  }
  
  storeLog(logEntry) {
    const logs = JSON.parse(localStorage.getItem('errorLogs') || '[]');
    logs.push(logEntry);
    
    // Keep only last 100 errors
    if (logs.length > 100) {
      logs.shift();
    }
    
    localStorage.setItem('errorLogs', JSON.stringify(logs));
  }
  
  getLogs() {
    return JSON.parse(localStorage.getItem('errorLogs') || '[]');
  }
}

const logger = new ErrorLogger();

// Usage
try {
  await apiCall();
} catch (error) {
  logger.log(error, {
    endpoint: '/orders/get-current',
    operation: 'fetch_orders'
  });
}
```

## User-Friendly Messages

<AccordionGroup>
  <Accordion title="Technical vs User Messages">
    ```javascript theme={null}
    function getUserMessage(error) {
      const messages = {
        401: 'Your session has expired. Please log in again.',
        403: 'You don\'t have permission to perform this action.',
        404: 'The requested item was not found.',
        422: 'Please check your input and try again.',
        429: 'Too many requests. Please wait a moment.',
        500: 'Something went wrong. Please try again later.'
      };
      
      return messages[error.status] || 
             'An unexpected error occurred. Please try again.';
    }
    ```
  </Accordion>

  <Accordion title="Error Notifications">
    ```javascript theme={null}
    function notifyUser(message, type = 'error') {
      const notification = {
        error: { color: 'red', icon: '❌' },
        warning: { color: 'orange', icon: '⚠️' },
        info: { color: 'blue', icon: 'ℹ️' }
      }[type];
      
      showToast(`${notification.icon} ${message}`, notification.color);
    }
    ```
  </Accordion>
</AccordionGroup>

## Complete Error Handling System

```javascript theme={null}
class APIClient {
  constructor() {
    this.retryHandler = new RetryHandler(3);
    this.logger = new ErrorLogger();
  }
  
  async request(endpoint, options = {}) {
    return this.retryHandler.execute(async () => {
      try {
        const response = await fetch(endpoint, {
          ...options,
          headers: {
            'Access-Token': await this.getToken(),
            'Content-Type': 'application/json',
            ...options.headers
          }
        });
        
        const data = await response.json();
        
        if (!data.status) {
          throw new APIError(
            response.status,
            data.error,
            data.message
          );
        }
        
        return data.data;
        
      } catch (error) {
        this.logger.log(error, {
          endpoint,
          method: options.method || 'GET',
          requestData: options.body
        });
        
        throw error;
      }
    });
  }
  
  async getToken() {
    // Token management logic
    return tokenManager.getValidToken();
  }
}

// Usage
const api = new APIClient();

try {
  const orders = await api.request('/orders/get-current');
  processOrders(orders);
} catch (error) {
  const message = getUserMessage(error);
  notifyUser(message);
}
```

## Monitoring & Alerts

Set up monitoring for:

* High error rates (> 5%)
* Repeated 401 errors (auth issues)
* Frequent 429 errors (rate limiting)
* 500 errors (server issues)
* Network timeouts

```javascript theme={null}
class ErrorMonitor {
  constructor() {
    this.errorCounts = {};
    this.alertThresholds = {
      401: 3,   // Alert after 3 auth errors
      429: 5,   // Alert after 5 rate limits
      500: 2    // Alert after 2 server errors
    };
  }
  
  recordError(error) {
    const code = error.status;
    this.errorCounts[code] = (this.errorCounts[code] || 0) + 1;
    
    if (this.shouldAlert(code)) {
      this.sendAlert(code, this.errorCounts[code]);
    }
  }
  
  shouldAlert(code) {
    const threshold = this.alertThresholds[code] || 10;
    return this.errorCounts[code] >= threshold;
  }
  
  sendAlert(code, count) {
    console.error(`🚨 ALERT: ${count} errors with code ${code}`);
    // Send to monitoring service
  }
}
```

<Card title="Need Help?" icon="question" href="mailto:support@dkkango.com">
  Having persistent errors? Contact our support team for assistance.
</Card>
