# 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` - **Проблема:** Логика погоды и новостей полностью продублирована. Изменения нужно вносить в два места. - **Решение:** Вынести общую логику в `utils/` (например, `utils/weather.py`, `utils/rss.py`) и использовать её из обоих мест. ### 4. `from datetime import datetime` внутри метода - **Где:** `commands/news.py` → `_format_and_send()`, строки 56 и 72 - **Проблема:** Импорт внутри метода — антипаттерн. Замедляет выполнение, нарушает PEP 8. - **Решение:** Перенести `from datetime import datetime` в начало файла. ### 5. Консольная команда `cat` — заглушка - **Где:** `console_commands/cat.py` - **Проблема:** Функция просто печатает `"🐱 тут должен быть котик"`. Заглушка видна пользователю. - **Решение:** Либо реализовать (вызвать API котиков), либо убрать из `ALL_CONSOLE_COMMANDS` и `README.md`. ### 6. `on_command_error` не сообщает пользователю об ошибке - **Где:** `bot.py` → `on_command_error()` - **Проблема:** Ошибки команд просто печатаются в `stdout`. Пользователь в чате не видит, что команда выполнилась с ошибкой. - **Решение:** Добавить `await ctx.send("Произошла ошибка при выполнении команды.")` или отправить embed с деталями (если `ctx` не None). ### 7. Нет `.gitignore` - **Где:** проект (файл отсутствует) - **Проблема:** Нет явного `.gitignore`. `.env` может случайно попасть в репозиторий, хотя AGENTS.md говорит "`.env` в `.gitignore`". - **Решение:** Создать `.gitignore` с правилами для Python (`__pycache__/`, `*.pyc`, `.env`, `venv/`, `*.egg-info/`). ### 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`.