telegram-cli-bot/HTML_ERROR_FIX.md

3.7 KiB
Raw Blame History

🐛 Исправление ошибки "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-тегов:

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