> ## Documentation Index
> Fetch the complete documentation index at: https://docs.g-tateth.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> Comprehensive guide to handling API errors and status codes

Proper error handling is essential for building robust integrations with the G-Tateth API. This guide covers all error types, status codes, and best practices.

## HTTP Status Codes

The G-Tateth API uses standard HTTP status codes to indicate success or failure:

### Success Codes

* **200 OK** - Request succeeded
* **201 Created** - Resource created successfully
* **204 No Content** - Request succeeded, no content to return

### Client Error Codes

* **400 Bad Request** - Invalid request parameters or malformed JSON
* **401 Unauthorized** - Missing or invalid authentication
* **403 Forbidden** - Insufficient permissions
* **404 Not Found** - Resource doesn't exist
* **409 Conflict** - Resource conflict (e.g., duplicate entry)
* **422 Unprocessable Entity** - Validation errors
* **429 Too Many Requests** - Rate limit exceeded

### Server Error Codes

* **500 Internal Server Error** - Unexpected server error
* **502 Bad Gateway** - Upstream service error
* **503 Service Unavailable** - Service temporarily unavailable
* **504 Gateway Timeout** - Request timeout

## Error Response Format

All error responses follow a consistent format:

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {
      "field": "Additional error details",
      "validation": "Specific validation errors"
    },
    "requestId": "req_1234567890",
    "timestamp": "2024-01-15T10:30:00Z"
  }
}
```

## Common Error Codes

### Authentication Errors

<Warning>
  Always check authentication before making requests.
</Warning>

#### `AUTH_REQUIRED`

**Status:** 401 Unauthorized

```json theme={null}
{
  "success": false,
  "error": {
    "code": "AUTH_REQUIRED",
    "message": "Authentication required",
    "details": {
      "hint": "Include a valid API key or Bearer token in the Authorization header"
    }
  }
}
```

**Solution:**

```javascript theme={null}
// Add Authorization header
headers: {
  'Authorization': `Bearer ${apiKey}`
}
```

#### `AUTH_INVALID`

**Status:** 401 Unauthorized

```json theme={null}
{
  "success": false,
  "error": {
    "code": "AUTH_INVALID",
    "message": "Invalid API key or token"
  }
}
```

**Solution:** Verify your API key is correct and hasn't been revoked.

#### `AUTH_EXPIRED`

**Status:** 401 Unauthorized

```json theme={null}
{
  "success": false,
  "error": {
    "code": "AUTH_EXPIRED",
    "message": "Token has expired",
    "details": {
      "expiredAt": "2024-01-15T10:00:00Z"
    }
  }
}
```

**Solution:** Refresh your token or generate a new API key.

### Validation Errors

#### `VALIDATION_ERROR`

**Status:** 422 Unprocessable Entity

```json theme={null}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "fields": {
        "email": ["Email is required", "Email format is invalid"],
        "phone": ["Phone number must be in E.164 format"]
      }
    }
  }
}
```

**Solution:** Fix the validation errors and retry the request.

### Rate Limiting

#### `RATE_LIMIT_EXCEEDED`

**Status:** 429 Too Many Requests

```json theme={null}
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded",
    "details": {
      "limit": 100,
      "remaining": 0,
      "resetAt": "2024-01-15T11:00:00Z"
    }
  }
}
```

**Solution:** Wait until `resetAt` or upgrade your plan for higher limits.

### Resource Errors

#### `RESOURCE_NOT_FOUND`

**Status:** 404 Not Found

```json theme={null}
{
  "success": false,
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "Conversation not found",
    "details": {
      "resource": "conversation",
      "id": "conv_123"
    }
  }
}
```

**Solution:** Verify the resource ID exists and you have access to it.

#### `RESOURCE_CONFLICT`

**Status:** 409 Conflict

```json theme={null}
{
  "success": false,
  "error": {
    "code": "RESOURCE_CONFLICT",
    "message": "Resource already exists",
    "details": {
      "resource": "api_key",
      "conflict": "Key with this name already exists"
    }
  }
}
```

**Solution:** Use a different identifier or update the existing resource.

### Permission Errors

#### `PERMISSION_DENIED`

**Status:** 403 Forbidden

```json theme={null}
{
  "success": false,
  "error": {
    "code": "PERMISSION_DENIED",
    "message": "Insufficient permissions",
    "details": {
      "required": "write:conversations",
      "granted": ["read:conversations"]
    }
  }
}
```

**Solution:** Use an API key with the required permissions or contact your administrator.

### Plan Limits

#### `PLAN_LIMIT_EXCEEDED`

**Status:** 403 Forbidden

```json theme={null}
{
  "success": false,
  "error": {
    "code": "PLAN_LIMIT_EXCEEDED",
    "message": "Plan limit exceeded",
    "details": {
      "limit": 1000,
      "current": 1001,
      "resource": "api_calls_per_month"
    }
  }
}
```

**Solution:** Upgrade your plan or wait for the next billing cycle.

## Error Handling Examples

### JavaScript/TypeScript

```typescript theme={null}
async function handleApiRequest(url: string, options: RequestInit) {
  try {
    const response = await fetch(url, options);
    const data = await response.json();
    
    if (!response.ok) {
      throw new ApiError(data.error, response.status);
    }
    
    return data;
  } catch (error) {
    if (error instanceof ApiError) {
      // Handle API errors
      switch (error.code) {
        case 'AUTH_REQUIRED':
        case 'AUTH_INVALID':
        case 'AUTH_EXPIRED':
          // Redirect to login or refresh token
          await refreshAuth();
          break;
        case 'RATE_LIMIT_EXCEEDED':
          // Wait and retry
          await waitForRateLimit(error.details.resetAt);
          break;
        case 'VALIDATION_ERROR':
          // Show validation errors to user
          showValidationErrors(error.details.fields);
          break;
        default:
          // Show generic error
          showError(error.message);
      }
    } else {
      // Handle network errors
      showError('Network error. Please check your connection.');
    }
    throw error;
  }
}

class ApiError extends Error {
  constructor(
    public error: {
      code: string;
      message: string;
      details?: any;
    },
    public status: number
  ) {
    super(error.message);
    this.name = 'ApiError';
  }
  
  get code() {
    return this.error.code;
  }
  
  get details() {
    return this.error.details;
  }
}
```

### Python

```python theme={null}
import requests
from typing import Dict, Any

class ApiError(Exception):
    def __init__(self, error: Dict[str, Any], status_code: int):
        self.code = error.get('code')
        self.message = error.get('message')
        self.details = error.get('details', {})
        self.status_code = status_code
        super().__init__(self.message)

def handle_api_request(url: str, method: str = 'GET', **kwargs) -> Dict:
    try:
        response = requests.request(method, url, **kwargs)
        data = response.json()
        
        if not response.ok:
            raise ApiError(data.get('error', {}), response.status_code)
        
        return data
    except requests.exceptions.RequestException as e:
        # Handle network errors
        raise Exception(f'Network error: {str(e)}')

# Usage with error handling
try:
    result = handle_api_request(
        'https://api.g-tateth.com/api/v1/conversations',
        headers={'Authorization': f'Bearer {api_key}'}
    )
except ApiError as e:
    if e.code == 'AUTH_REQUIRED':
        # Refresh authentication
        refresh_auth()
    elif e.code == 'RATE_LIMIT_EXCEEDED':
        # Wait and retry
        wait_for_rate_limit(e.details.get('resetAt'))
    else:
        print(f'API Error: {e.message}')
```

### PHP

```php theme={null}
<?php

class ApiError extends Exception {
    public $code;
    public $details;
    public $statusCode;
    
    public function __construct($error, $statusCode) {
        $this->code = $error['code'] ?? 'UNKNOWN_ERROR';
        $this->details = $error['details'] ?? [];
        $this->statusCode = $statusCode;
        parent::__construct($error['message'] ?? 'Unknown error');
    }
}

function handleApiRequest($url, $options = []) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => $options['headers'] ?? [],
        CURLOPT_CUSTOMREQUEST => $options['method'] ?? 'GET',
        CURLOPT_POSTFIELDS => isset($options['body']) ? json_encode($options['body']) : null,
    ]);
    
    $response = curl_exec($ch);
    $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    $data = json_decode($response, true);
    
    if ($statusCode >= 400) {
        throw new ApiError($data['error'] ?? [], $statusCode);
    }
    
    return $data;
}

// Usage
try {
    $result = handleApiRequest(
        'https://api.g-tateth.com/api/v1/conversations',
        [
            'headers' => [
                'Authorization: Bearer ' . $apiKey,
                'Content-Type: application/json'
            ]
        ]
    );
} catch (ApiError $e) {
    switch ($e->code) {
        case 'AUTH_REQUIRED':
            refreshAuth();
            break;
        case 'RATE_LIMIT_EXCEEDED':
            waitForRateLimit($e->details['resetAt']);
            break;
        default:
            echo "API Error: " . $e->getMessage();
    }
}
```

## Retry Logic

Implement exponential backoff for retryable errors:

```javascript theme={null}
async function retryRequest(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      
      // Only retry on specific errors
      const retryableErrors = [
        'RATE_LIMIT_EXCEEDED',
        'SERVER_ERROR',
        'TIMEOUT'
      ];
      
      if (!retryableErrors.includes(error.code)) {
        throw error;
      }
      
      // Exponential backoff: 1s, 2s, 4s
      const delay = Math.pow(2, i) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}
```

## Best Practices

### 1. Always Check Response Status

```javascript theme={null}
// ❌ Bad
const data = await response.json();

// ✅ Good
if (!response.ok) {
  const error = await response.json();
  throw new ApiError(error.error, response.status);
}
const data = await response.json();
```

### 2. Handle Network Errors

```javascript theme={null}
try {
  const response = await fetch(url);
} catch (error) {
  if (error instanceof TypeError) {
    // Network error
    console.error('Network error:', error.message);
  } else {
    // Other error
    throw error;
  }
}
```

### 3. Log Errors for Debugging

```javascript theme={null}
catch (error) {
  console.error('API Error:', {
    code: error.code,
    message: error.message,
    details: error.details,
    requestId: error.requestId,
    url: error.url
  });
  throw error;
}
```

### 4. Provide User-Friendly Messages

```javascript theme={null}
const errorMessages = {
  'AUTH_REQUIRED': 'Please log in to continue',
  'RATE_LIMIT_EXCEEDED': 'Too many requests. Please try again later.',
  'VALIDATION_ERROR': 'Please check your input and try again.',
  'RESOURCE_NOT_FOUND': 'The requested item could not be found.'
};

function getUserMessage(error) {
  return errorMessages[error.code] || error.message;
}
```

### 5. Use Request IDs for Support

Always include the `requestId` when contacting support:

```javascript theme={null}
catch (error) {
  if (error.requestId) {
    console.error(`Request ID: ${error.requestId}`);
    // Include in support ticket
  }
}
```

## Testing Error Handling

Test your error handling with different scenarios:

```javascript theme={null}
// Test authentication errors
test('handles invalid API key', async () => {
  const response = await apiRequest('/conversations', {
    headers: { 'Authorization': 'Bearer invalid' }
  });
  expect(response.status).toBe(401);
});

// Test validation errors
test('handles validation errors', async () => {
  const response = await apiRequest('/conversations', {
    method: 'POST',
    body: { invalid: 'data' }
  });
  expect(response.status).toBe(422);
});

// Test rate limiting
test('handles rate limits', async () => {
  // Make many requests
  for (let i = 0; i < 100; i++) {
    await apiRequest('/conversations');
  }
  const response = await apiRequest('/conversations');
  expect(response.status).toBe(429);
});
```

## Support

If you encounter an error that isn't documented here:

1. Check the error `requestId` in the response
2. Review the error `details` for additional context
3. Contact support with the `requestId` and error details
4. Check our [status page](https://status.g-tateth.com) for service issues

**Support Email:** [support@g-tateth.com](mailto:support@g-tateth.com)
