3.7 KiB
3.7 KiB
🐛 Исправление ошибки "Can't parse entities"
Проблема
Бот получал ошибки при отправке длинных HTML-сообщений:
telegram.error.BadRequest: Can't parse entities: unexpected end tag at byte offset 1381
telegram.error.BadRequest: Message is too long
Причина
send_long_message_htmlполучал текст с HTML-тегами от Qwen- Пытался конвертировать его из Markdown → HTML (двойная конвертация)
- При разбивке на части HTML-теги разрывались (
<b>в одной части,</b>в другой) - Telegram отклонял сообщения с битыми тегами
Решение
1. Улучшена обработка ошибок в send_long_message
Файл: bot/utils/formatters.py
Добавлен fallback для битых HTML-тегов:
except Exception as e:
logger.warning(f"Ошибка HTML (parse_mode={actual_parse_mode}): {e}")
# Проверяем это ошибка парсинга HTML — пробуем экранировать
if "parse" in str(e).lower() or "tag" in str(e).lower():
import html as html_lib
safe_part = html_lib.escape(part)
try:
await send_method(safe_part, parse_mode=None)
except Exception as e2:
# Последняя попытка — обрезать до безопасного размера
safe_part = safe_part[:4000] + "... (обрезано)"
await send_method(safe_part, parse_mode=None)
2. Улучшена обработка в send_long_message_html
Добавлен многоуровневый fallback:
try:
return await send_long_message(update, html_text, parse_mode=ParseMode.HTML, ...)
except Exception as e:
logger.warning(f"Ошибка отправки HTML: {e}")
# Если HTML не работает — экранируем и отправляем как plain text
escaped_text = html_lib.escape(html_text)
try:
return await send_long_message(update, escaped_text, parse_mode=None, ...)
except Exception as e2:
# Последний fallback — обрезаем до безопасного размера
safe_text = escaped_text[:4000] + "... (обрезано)"
return await send_long_message(update, safe_text, parse_mode=None, ...)
Уровни защиты
| Уровень | Действие | Когда |
|---|---|---|
| 1 | Отправка HTML | Нормальная работа |
| 2 | Экранирование HTML | Битые теги |
| 3 | Обрезка до 4000 символов | Слишком длинное сообщение |
Тестирование
Проверьте отправку длинных сообщений:
# Отправьте боту запрос который вернёт длинный ответ
"Напиши подробное руководство по Python asyncio"
Ожидаемое поведение:
- Короткие сообщения отправляются в HTML
- Длинные сообщения разбиваются на части
- При ошибках HTML — экранируются и отправляются как текст
- Сообщения >4000 символов обрезаются с уведомлением
Файлы изменены
bot/utils/formatters.py— улучшена обработка ошибок HTML
Дата исправления: 2026-03-09
Версия бота: 0.9.0