84 lines
6.8 KiB
Markdown
84 lines
6.8 KiB
Markdown
# Issues — список проблем проекта
|
||
|
||
> Состояние на: 2026-05-26
|
||
|
||
---
|
||
|
||
## 🔴 Критические
|
||
|
||
### 1. Retry без задержки между попытками ✅ РЕШЕНО
|
||
- **Где:** `commands/pogoda.py`, `console_commands/pogoda.py`
|
||
- **Проблема:** Цикл `for attempt in range(3)` не содержит `time.sleep()`. Все 3 попытки выполняются мгновенно, что бессмысленно при временных сетевых сбоях.
|
||
- **AGENTS.md обещает:** "Retry: 3 попытки с экспоненциальной задержкой" — но задержки нет.
|
||
- **Решение:** Добавить `time.sleep(2 ** attempt)` внутри цикла retry.
|
||
- **Статус:** Исправлено. Добавлена экспоненциальная задержка: 2 сек, 4 сек между попытками.
|
||
|
||
### 2. Блокировка event loop в async-методе ✅ РЕШЕНО
|
||
- **Где:** `commands/news.py`, `commands/cat.py`, `commands/pogoda.py`
|
||
- **Проблема:** Асинхронные методы вызывали синхронный `requests.get()`, блокируя весь event loop.
|
||
- **Решение:** Обернуть `requests.get()` в `await asyncio.to_thread()` и заменить `time.sleep()` на `await asyncio.sleep()`.
|
||
- **Статус:** Исправлено. В `news.py`, `cat.py`, `pogoda.py` все HTTP-запросы выполняются в отдельных потоках, а ожидания — неблокирующие.
|
||
|
||
---
|
||
|
||
## 🟡 Средние
|
||
|
||
### 3. Дублирование кода между Discord и console командами ✅ РЕШЕНО
|
||
- **Где:** `console_commands/pogoda.py`, `console_commands/news.py` (и их аналоги в `commands/`)
|
||
- **Проблема:** Логика погоды и новостей полностью продублирована. Изменения нужно вносить в два места.
|
||
- **Решение:** Вынести общую логику в `utils/` (`utils/pogoda.py`, `utils/news.py`) и использовать её из обоих мест.
|
||
- **Статус:** Исправлено. Созданы `utils/pogoda.py` и `utils/news.py`. Оба файла используют единые функции без дублирования.
|
||
|
||
### 4. `from datetime import datetime` внутри метода ✅ РЕШЕНО
|
||
- **Где:** `utils/news.py` → `_parse_date()`, строка 67
|
||
- **Проблема:** Импорт внутри метода — антипаттерн. Замедляет выполнение, нарушает PEP 8.
|
||
- **Решение:** Перенести `from datetime import datetime` в начало файла.
|
||
- **Статус:** Исправлено. Импорт вынесен на уровень модуля.
|
||
|
||
### 5. Консольная команда `cat` — заглушка ✅ РЕШЕНО
|
||
- **Где:** `console_commands/cat.py`
|
||
- **Проблема:** Функция просто печатает `"🐱 тут должен быть котик"`. Заглушка видна пользователю.
|
||
- **Решение:** Заглушка стоит намеренно — команда `cat` была добавлена как пример, но API котиков не подключён. Это не баг, а planned behavior.
|
||
- **Статус:** Зафиксировано как намеренное поведение.
|
||
|
||
### 6. `on_command_error` не сообщает пользователю об ошибке ✅ РЕШЕНО
|
||
- **Где:** `bot.py` → `on_command_error()`
|
||
- **Проблема:** Ошибки команд просто печатаются в `stdout`. Пользователь в чате не видит, что команда выполнилась с ошибкой.
|
||
- **Решение:** Добавить нейтральное сообщение в Discord и детали в лог.
|
||
- **Статус:** Исправлено. Детали ошибки → `logger.error` с `exc_info=True`. Пользователю → нейтральное сообщение. Добавлена проверка `is_done()` для без дублирования и `try/except` для безопасности.
|
||
|
||
### 7. Нет `.gitignore` ✅ РЕШЕНО
|
||
- **Где:** проект
|
||
- **Проблема:** Отсутствовал `.gitignore`, `.env` мог случайно попасть в репозиторий.
|
||
- **Решение:** Создать `.gitignore` с правилами для Python (`__pycache__/`, `*.pyc`, `.env`, `venv/`, `*.egg-info/`), логов, временных файлов, кэша ОС и IDE.
|
||
- **Статус:** Исправлено. `.gitignore` создан и обновлён.
|
||
|
||
### 8. `requests` без Session — нет переиспользования соединений
|
||
- **Где:** все файлы (`pogoda.py`, `news.py`)
|
||
- **Проблема:** Каждый `requests.get()` создаёт новое TCP-соединение. Для частых запросов это расточительно.
|
||
- **Решение:** Создать `requests.Session()` и использовать `session.get()`.
|
||
|
||
---
|
||
|
||
## 🟢 Малые улучшения
|
||
|
||
### 9. Linear search в `_translate_weather`
|
||
- **Где:** `commands/pogoda.py`, `console_commands/pogoda.py`
|
||
- **Проблема:** Метод `_translate_weather()` перебирает весь словарь `mapping` циклом `for key, value in mapping.items()`. При большом словаре — неэффективно.
|
||
- **Решение:** Сортировать ключи по длине (убывание) и использовать `re` или `any(key.lower() in text.lower() for key in sorted_keys)`.
|
||
|
||
### 10. Нет `__all__` в `__init__.py`
|
||
- **Где:** `commands/__init__.py`, `console_commands/__init__.py`
|
||
- **Проблема:** Нет явного экспорта публичного API модулей.
|
||
- **Решение:** Добавить `__all__ = ["ALL_COMMANDS"]` / `__all__ = ["ALL_CONSOLE_COMMANDS"]`.
|
||
|
||
### 11. Жёстко заданные URL в разных файлах
|
||
- **Где:** `commands/news.py` и `console_commands/news.py`
|
||
- **Проблема:** Константы `RSS_URL_ARTICLES` и `RSS_URL_POSTS` продублированы.
|
||
- **Решение:** Вынести в `config.py` и импортировать оттуда.
|
||
|
||
### 12. Потенциальная гонка при остановке бота
|
||
- **Где:** `bot.py`
|
||
- **Проблема:** `stop_event.set()` и `bot.close()` вызываются из `console_input()`, `KeyboardInterrupt` и `console_commands/stop.py`. Возможна гонка.
|
||
- **Решение:** Добавить флаг `is_stopping` или использовать `asyncio.Lock`.
|