telegram-cli-bot/HTML_ERROR_FIX.md

95 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🐛 Исправление ошибки "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
```
## Причина
1. **`send_long_message_html`** получал текст с HTML-тегами от Qwen
2. Пытался конвертировать его из Markdown → HTML (двойная конвертация)
3. При разбивке на части HTML-теги разрывались (`<b>` в одной части, `</b>` в другой)
4. Telegram отклонял сообщения с битыми тегами
## Решение
### 1. Улучшена обработка ошибок в `send_long_message`
**Файл:** `bot/utils/formatters.py`
Добавлен fallback для битых HTML-тегов:
```python
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:
```python
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 символов | Слишком длинное сообщение |
## Тестирование
Проверьте отправку длинных сообщений:
```bash
# Отправьте боту запрос который вернёт длинный ответ
"Напиши подробное руководство по Python asyncio"
```
**Ожидаемое поведение:**
- Короткие сообщения отправляются в HTML
- Длинные сообщения разбиваются на части
- При ошибках HTML — экранируются и отправляются как текст
- Сообщения >4000 символов обрезаются с уведомлением
## Файлы изменены
- `bot/utils/formatters.py` — улучшена обработка ошибок HTML
---
**Дата исправления:** 2026-03-09
**Версия бота:** 0.9.0