203 lines
5.9 KiB
Python
203 lines
5.9 KiB
Python
"""
|
||
Исключения Kwork API.
|
||
|
||
Все исключения предоставляют понятные сообщения для отладки.
|
||
Иерархия исключений:
|
||
|
||
KworkError (базовое)
|
||
├── KworkAuthError (ошибки аутентификации)
|
||
├── KworkApiError (HTTP ошибки API)
|
||
│ ├── KworkNotFoundError (404)
|
||
│ ├── KworkRateLimitError (429)
|
||
│ └── KworkValidationError (400)
|
||
└── KworkNetworkError (ошибки сети)
|
||
"""
|
||
|
||
from typing import Any
|
||
|
||
__all__ = [
|
||
"KworkError",
|
||
"KworkAuthError",
|
||
"KworkApiError",
|
||
"KworkNotFoundError",
|
||
"KworkRateLimitError",
|
||
"KworkValidationError",
|
||
"KworkNetworkError",
|
||
]
|
||
|
||
|
||
class KworkError(Exception):
|
||
"""
|
||
Базовое исключение для всех ошибок Kwork API.
|
||
|
||
Все остальные исключения наследуются от этого класса.
|
||
|
||
Attributes:
|
||
message: Сообщение об ошибке.
|
||
response: Оригинальный HTTP response (если есть).
|
||
|
||
Example:
|
||
try:
|
||
await client.catalog.get_list()
|
||
except KworkError as e:
|
||
print(f"Ошибка: {e.message}")
|
||
"""
|
||
|
||
def __init__(self, message: str, response: Any | None = None):
|
||
self.message = message
|
||
self.response = response
|
||
super().__init__(self.message)
|
||
|
||
def __str__(self) -> str:
|
||
return f"KworkError: {self.message}"
|
||
|
||
|
||
class KworkAuthError(KworkError):
|
||
"""
|
||
Ошибка аутентификации/авторизации.
|
||
|
||
Возникает при:
|
||
- Неверном логине или пароле
|
||
- Истёкшем или невалидном токене
|
||
- Отсутствии прав доступа (403)
|
||
|
||
Example:
|
||
try:
|
||
client = await KworkClient.login("user", "wrong_password")
|
||
except KworkAuthError:
|
||
print("Неверные учётные данные")
|
||
"""
|
||
|
||
def __init__(self, message: str = "Authentication failed", response: Any | None = None):
|
||
super().__init__(message, response)
|
||
|
||
def __str__(self) -> str:
|
||
return f"KworkAuthError: {self.message}"
|
||
|
||
|
||
class KworkApiError(KworkError):
|
||
"""
|
||
Ошибка HTTP запроса к API (4xx, 5xx).
|
||
|
||
Базовый класс для HTTP ошибок API. Содержит код статуса.
|
||
|
||
Attributes:
|
||
status_code: HTTP код ответа (400, 404, 500, etc.)
|
||
|
||
Example:
|
||
try:
|
||
await client.catalog.get_details(999999)
|
||
except KworkApiError as e:
|
||
print(f"HTTP {e.status_code}: {e.message}")
|
||
"""
|
||
|
||
def __init__(
|
||
self,
|
||
message: str,
|
||
status_code: int | None = None,
|
||
response: Any | None = None,
|
||
):
|
||
self.status_code = status_code
|
||
super().__init__(message, response)
|
||
|
||
def __str__(self) -> str:
|
||
if self.status_code:
|
||
return f"KworkApiError [{self.status_code}]: {self.message}"
|
||
return f"KworkApiError: {self.message}"
|
||
|
||
|
||
class KworkNotFoundError(KworkApiError):
|
||
"""
|
||
Ресурс не найден (404).
|
||
|
||
Возникает при запросе несуществующего кворка,
|
||
пользователя или другого ресурса.
|
||
|
||
Example:
|
||
try:
|
||
await client.catalog.get_details(999999)
|
||
except KworkNotFoundError:
|
||
print("Кворк не найден")
|
||
"""
|
||
|
||
def __init__(self, resource: str, response: Any | None = None):
|
||
super().__init__(f"Resource not found: {resource}", 404, response)
|
||
|
||
|
||
class KworkRateLimitError(KworkApiError):
|
||
"""
|
||
Превышен лимит запросов (429).
|
||
|
||
Возникает при слишком частых запросах к API.
|
||
Рекомендуется сделать паузу перед повторным запросом.
|
||
|
||
Example:
|
||
import asyncio
|
||
|
||
try:
|
||
await client.catalog.get_list()
|
||
except KworkRateLimitError:
|
||
await asyncio.sleep(5) # Пауза 5 секунд
|
||
"""
|
||
|
||
def __init__(self, message: str = "Rate limit exceeded", response: Any | None = None):
|
||
super().__init__(message, 429, response)
|
||
|
||
|
||
class KworkValidationError(KworkApiError):
|
||
"""
|
||
Ошибка валидации (400).
|
||
|
||
Возникает при некорректных данных запроса.
|
||
|
||
Attributes:
|
||
fields: Словарь ошибок по полям {field: [errors]}.
|
||
|
||
Example:
|
||
try:
|
||
await client.catalog.get_list(page=-1)
|
||
except KworkValidationError as e:
|
||
if e.fields:
|
||
for field, errors in e.fields.items():
|
||
print(f"{field}: {errors[0]}")
|
||
"""
|
||
|
||
def __init__(
|
||
self,
|
||
message: str = "Validation failed",
|
||
fields: dict[str, list[str]] | None = None,
|
||
response: Any | None = None,
|
||
):
|
||
self.fields = fields or {}
|
||
super().__init__(message, 400, response)
|
||
|
||
def __str__(self) -> str:
|
||
if self.fields:
|
||
field_errors = ", ".join(f"{k}: {v[0]}" for k, v in self.fields.items())
|
||
return f"KworkValidationError: {field_errors}"
|
||
return f"KworkValidationError: {self.message}"
|
||
|
||
|
||
class KworkNetworkError(KworkError):
|
||
"""
|
||
Ошибка сети/подключения.
|
||
|
||
Возникает при:
|
||
- Отсутствии соединения
|
||
- Таймауте запроса
|
||
- Ошибке DNS
|
||
- Проблемах с SSL
|
||
|
||
Example:
|
||
try:
|
||
await client.catalog.get_list()
|
||
except KworkNetworkError:
|
||
print("Проверьте подключение к интернету")
|
||
"""
|
||
|
||
def __init__(self, message: str = "Network error", response: Any | None = None):
|
||
super().__init__(message, response)
|
||
|
||
def __str__(self) -> str:
|
||
return f"KworkNetworkError: {self.message}"
|