Integrate OpenAPI/Swagger documentation using drf-spectacular, enhancing API documentation with comprehensive guides and schema generation. Add multiple documentation files covering authentication, error codes, rate limiting, and migration strategies. Update settings and URLs to support new documentation endpoints and schema configurations.
This commit is contained in:
407
docs/ERROR-CODES.md
Normal file
407
docs/ERROR-CODES.md
Normal file
@@ -0,0 +1,407 @@
|
||||
# API Error Codes Reference
|
||||
|
||||
**Version**: 1.0.0
|
||||
**Last Updated**: 2025-11-16
|
||||
|
||||
This document provides a comprehensive reference for all error codes and error scenarios in the IGNY8 API v1.0.
|
||||
|
||||
---
|
||||
|
||||
## Error Response Format
|
||||
|
||||
All errors follow this unified format:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Error message",
|
||||
"errors": {
|
||||
"field_name": ["Field-specific errors"]
|
||||
},
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## HTTP Status Codes
|
||||
|
||||
### 200 OK
|
||||
**Meaning**: Request successful
|
||||
**Response**: Success response with data
|
||||
|
||||
### 201 Created
|
||||
**Meaning**: Resource created successfully
|
||||
**Response**: Success response with created resource data
|
||||
|
||||
### 204 No Content
|
||||
**Meaning**: Resource deleted successfully
|
||||
**Response**: Empty response body
|
||||
|
||||
### 400 Bad Request
|
||||
**Meaning**: Validation error or invalid request
|
||||
**Common Causes**:
|
||||
- Missing required fields
|
||||
- Invalid field values
|
||||
- Invalid data format
|
||||
- Business logic validation failures
|
||||
|
||||
**Example**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Validation failed",
|
||||
"errors": {
|
||||
"email": ["This field is required"],
|
||||
"password": ["Password must be at least 8 characters"]
|
||||
},
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
### 401 Unauthorized
|
||||
**Meaning**: Authentication required
|
||||
**Common Causes**:
|
||||
- Missing Authorization header
|
||||
- Invalid or expired token
|
||||
- Token not provided
|
||||
|
||||
**Example**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Authentication required",
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
### 403 Forbidden
|
||||
**Meaning**: Permission denied
|
||||
**Common Causes**:
|
||||
- User lacks required role
|
||||
- User doesn't have access to resource
|
||||
- Account/site/sector access denied
|
||||
|
||||
**Example**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Permission denied",
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
### 404 Not Found
|
||||
**Meaning**: Resource not found
|
||||
**Common Causes**:
|
||||
- Invalid resource ID
|
||||
- Resource doesn't exist
|
||||
- Resource belongs to different account
|
||||
|
||||
**Example**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Resource not found",
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
### 409 Conflict
|
||||
**Meaning**: Resource conflict
|
||||
**Common Causes**:
|
||||
- Duplicate resource (e.g., email already exists)
|
||||
- Resource state conflict
|
||||
- Concurrent modification
|
||||
|
||||
**Example**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Conflict",
|
||||
"errors": {
|
||||
"email": ["User with this email already exists"]
|
||||
},
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
### 422 Unprocessable Entity
|
||||
**Meaning**: Validation failed
|
||||
**Common Causes**:
|
||||
- Complex validation rules failed
|
||||
- Business logic validation failed
|
||||
- Data integrity constraints violated
|
||||
|
||||
**Example**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Validation failed",
|
||||
"errors": {
|
||||
"site": ["Site must belong to your account"],
|
||||
"sector": ["Sector must belong to the selected site"]
|
||||
},
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
### 429 Too Many Requests
|
||||
**Meaning**: Rate limit exceeded
|
||||
**Common Causes**:
|
||||
- Too many requests in time window
|
||||
- AI function rate limit exceeded
|
||||
- Authentication rate limit exceeded
|
||||
|
||||
**Response Headers**:
|
||||
- `X-Throttle-Limit`: Maximum requests allowed
|
||||
- `X-Throttle-Remaining`: Remaining requests (0)
|
||||
- `X-Throttle-Reset`: Unix timestamp when limit resets
|
||||
|
||||
**Example**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Rate limit exceeded",
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
**Solution**: Wait until `X-Throttle-Reset` timestamp before retrying.
|
||||
|
||||
### 500 Internal Server Error
|
||||
**Meaning**: Server error
|
||||
**Common Causes**:
|
||||
- Unexpected server error
|
||||
- Database error
|
||||
- External service failure
|
||||
|
||||
**Example**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Internal server error",
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
**Solution**: Retry request. If persistent, contact support with `request_id`.
|
||||
|
||||
---
|
||||
|
||||
## Field-Specific Error Messages
|
||||
|
||||
### Authentication Errors
|
||||
|
||||
| Field | Error Message | Description |
|
||||
|-------|---------------|-------------|
|
||||
| `email` | "This field is required" | Email not provided |
|
||||
| `email` | "Invalid email format" | Email format invalid |
|
||||
| `email` | "User with this email already exists" | Email already registered |
|
||||
| `password` | "This field is required" | Password not provided |
|
||||
| `password` | "Password must be at least 8 characters" | Password too short |
|
||||
| `password` | "Invalid credentials" | Wrong password |
|
||||
|
||||
### Planner Module Errors
|
||||
|
||||
| Field | Error Message | Description |
|
||||
|-------|---------------|-------------|
|
||||
| `seed_keyword_id` | "This field is required" | Seed keyword not provided |
|
||||
| `seed_keyword_id` | "Invalid seed keyword" | Seed keyword doesn't exist |
|
||||
| `site_id` | "This field is required" | Site not provided |
|
||||
| `site_id` | "Site must belong to your account" | Site access denied |
|
||||
| `sector_id` | "This field is required" | Sector not provided |
|
||||
| `sector_id` | "Sector must belong to the selected site" | Sector-site mismatch |
|
||||
| `status` | "Invalid status value" | Status value not allowed |
|
||||
|
||||
### Writer Module Errors
|
||||
|
||||
| Field | Error Message | Description |
|
||||
|-------|---------------|-------------|
|
||||
| `title` | "This field is required" | Title not provided |
|
||||
| `site_id` | "This field is required" | Site not provided |
|
||||
| `sector_id` | "This field is required" | Sector not provided |
|
||||
| `image_type` | "Invalid image type" | Image type not allowed |
|
||||
|
||||
### System Module Errors
|
||||
|
||||
| Field | Error Message | Description |
|
||||
|-------|---------------|-------------|
|
||||
| `api_key` | "This field is required" | API key not provided |
|
||||
| `api_key` | "Invalid API key format" | API key format invalid |
|
||||
| `integration_type` | "Invalid integration type" | Integration type not allowed |
|
||||
|
||||
### Billing Module Errors
|
||||
|
||||
| Field | Error Message | Description |
|
||||
|-------|---------------|-------------|
|
||||
| `amount` | "This field is required" | Amount not provided |
|
||||
| `amount` | "Amount must be positive" | Invalid amount value |
|
||||
| `credits` | "Insufficient credits" | Not enough credits available |
|
||||
|
||||
---
|
||||
|
||||
## Error Handling Best Practices
|
||||
|
||||
### 1. Always Check `success` Field
|
||||
|
||||
```python
|
||||
response = requests.get(url, headers=headers)
|
||||
data = response.json()
|
||||
|
||||
if data['success']:
|
||||
# Handle success
|
||||
result = data['data'] or data['results']
|
||||
else:
|
||||
# Handle error
|
||||
error_message = data['error']
|
||||
field_errors = data.get('errors', {})
|
||||
```
|
||||
|
||||
### 2. Handle Field-Specific Errors
|
||||
|
||||
```python
|
||||
if not data['success']:
|
||||
if 'errors' in data:
|
||||
for field, errors in data['errors'].items():
|
||||
print(f"{field}: {', '.join(errors)}")
|
||||
else:
|
||||
print(f"Error: {data['error']}")
|
||||
```
|
||||
|
||||
### 3. Use Request ID for Support
|
||||
|
||||
```python
|
||||
if not data['success']:
|
||||
request_id = data.get('request_id')
|
||||
print(f"Error occurred. Request ID: {request_id}")
|
||||
# Include request_id when contacting support
|
||||
```
|
||||
|
||||
### 4. Handle Rate Limiting
|
||||
|
||||
```python
|
||||
if response.status_code == 429:
|
||||
reset_time = response.headers.get('X-Throttle-Reset')
|
||||
wait_seconds = int(reset_time) - int(time.time())
|
||||
print(f"Rate limited. Wait {wait_seconds} seconds.")
|
||||
time.sleep(wait_seconds)
|
||||
# Retry request
|
||||
```
|
||||
|
||||
### 5. Retry on Server Errors
|
||||
|
||||
```python
|
||||
if response.status_code >= 500:
|
||||
# Retry with exponential backoff
|
||||
time.sleep(2 ** retry_count)
|
||||
# Retry request
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Error Scenarios
|
||||
|
||||
### Scenario 1: Missing Authentication
|
||||
|
||||
**Request**:
|
||||
```http
|
||||
GET /api/v1/planner/keywords/
|
||||
(No Authorization header)
|
||||
```
|
||||
|
||||
**Response** (401):
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Authentication required",
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
**Solution**: Include `Authorization: Bearer <token>` header.
|
||||
|
||||
### Scenario 2: Invalid Resource ID
|
||||
|
||||
**Request**:
|
||||
```http
|
||||
GET /api/v1/planner/keywords/99999/
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Response** (404):
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Resource not found",
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
**Solution**: Verify resource ID exists and belongs to your account.
|
||||
|
||||
### Scenario 3: Validation Error
|
||||
|
||||
**Request**:
|
||||
```http
|
||||
POST /api/v1/planner/keywords/
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"seed_keyword_id": null,
|
||||
"site_id": 1
|
||||
}
|
||||
```
|
||||
|
||||
**Response** (400):
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Validation failed",
|
||||
"errors": {
|
||||
"seed_keyword_id": ["This field is required"],
|
||||
"sector_id": ["This field is required"]
|
||||
},
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
**Solution**: Provide all required fields with valid values.
|
||||
|
||||
### Scenario 4: Rate Limit Exceeded
|
||||
|
||||
**Request**: Multiple rapid requests
|
||||
|
||||
**Response** (429):
|
||||
```http
|
||||
HTTP/1.1 429 Too Many Requests
|
||||
X-Throttle-Limit: 60
|
||||
X-Throttle-Remaining: 0
|
||||
X-Throttle-Reset: 1700123456
|
||||
|
||||
{
|
||||
"success": false,
|
||||
"error": "Rate limit exceeded",
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
**Solution**: Wait until `X-Throttle-Reset` timestamp, then retry.
|
||||
|
||||
---
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
1. **Always include `request_id`** when reporting errors
|
||||
2. **Check response headers** for rate limit information
|
||||
3. **Verify authentication token** is valid and not expired
|
||||
4. **Check field-specific errors** in `errors` object
|
||||
5. **Review request payload** matches API specification
|
||||
6. **Use Swagger UI** to test endpoints interactively
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-11-16
|
||||
**API Version**: 1.0.0
|
||||
|
||||
Reference in New Issue
Block a user