Обработка ошибок
Стандартизированный формат ошибок и коды
Формат ошибок
Все ошибки API возвращаются в едином стандартизированном формате:
{
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": "fieldName",
"value": "invalidValue"
}
}
-
code- уникальный код ошибки (для программной обработки) -
message- понятное человеку описание ошибки -
details- дополнительная информация (опционально)
HTTP Status Codes
| Код | Название | Описание |
|---|---|---|
| 200 | OK | Запрос выполнен успешно |
| 201 | Created | Ресурс создан успешно |
| 204 | No Content | Запрос выполнен, нет данных для возврата |
| 400 | Bad Request | Неверный формат запроса |
| 401 | Unauthorized | Требуется аутентификация |
| 403 | Forbidden | Недостаточно прав доступа |
| 404 | Not Found | Ресурс не найден |
| 409 | Conflict | Конфликт данных (дубликат) |
| 429 | Too Many Requests | Превышен rate limit |
| 500 | Internal Server Error | Внутренняя ошибка сервера |
| 503 | Service Unavailable | Сервис временно недоступен |
Коды ошибок
| Код | HTTP Status | Описание |
|---|---|---|
validation_error |
400 | Ошибка валидации входных данных |
invalid_request |
400 | Неверный формат запроса |
unauthorized |
401 | Требуется аутентификация |
invalid_token |
401 | Недействительный JWT токен |
token_expired |
401 | Токен истек |
forbidden |
403 | Недостаточно прав доступа |
not_found |
404 | Ресурс не найден |
user_exists |
409 | Пользователь уже существует |
conflict |
409 | Конфликт данных |
rate_limit_exceeded |
429 | Превышен лимит запросов |
internal_error |
500 | Внутренняя ошибка сервера |
database_error |
500 | Ошибка базы данных |
service_unavailable |
503 | Сервис временно недоступен |
Примеры ошибок
Validation Error (400)
{
"code": "validation_error",
"message": "Invalid email format",
"details": {
"field": "email",
"value": "invalid-email"
}
}
Unauthorized (401)
{
"code": "unauthorized",
"message": "Authentication required"
}
Forbidden (403)
{
"code": "forbidden",
"message": "You don't have permission to perform this action",
"details": {
"required_permission": "MANAGE_SERVER"
}
}
Not Found (404)
{
"code": "not_found",
"message": "Server not found",
"details": {
"resource": "server",
"id": 123
}
}
Rate Limit (429)
{
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please try again later.",
"details": {
"retry_after": 60,
"limit": 100,
"window": "1 minute"
}
}
Обработка ошибок (JavaScript)
Базовая обработка
async function apiRequest(url, options) {
try {
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
throw new APIError(error.code, error.message, error.details);
}
return await response.json();
} catch (error) {
if (error instanceof APIError) {
handleAPIError(error);
} else {
console.error('Network error:', error);
}
throw error;
}
}
class APIError extends Error {
constructor(code, message, details) {
super(message);
this.code = code;
this.details = details;
}
}
Обработка специфичных ошибок
function handleAPIError(error) {
switch (error.code) {
case 'unauthorized':
case 'token_expired':
redirectToLogin();
break;
case 'forbidden':
showError('У вас нет прав для этого действия');
break;
case 'rate_limit_exceeded':
const retryAfter = error.details?.retry_after || 60;
showError(`Слишком много запросов. Попробуйте через ${retryAfter} секунд`);
break;
case 'validation_error':
const field = error.details?.field;
showFieldError(field, error.message);
break;
case 'not_found':
show404Page();
break;
default:
showError(error.message || 'Произошла ошибка');
}
}
Best Practices
- Всегда проверяйте HTTP status code перед парсингом ответа
- Обрабатывайте ошибки gracefully с понятными сообщениями для пользователя
- Логируйте детали ошибок для debugging (но не показывайте пользователю)
- Используйте retry logic для 5xx ошибок
- Не повторяйте запросы для 4xx ошибок (кроме 429)
- Обрабатывайте 401/403 ошибки с редиректом на логин
- Показывайте пользователю понятные сообщения, а не технические детали