[ВОЛК] Переход evtg_publish на httpx_client
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2025-12-21 19:14:08 +03:00
parent e3de30e429
commit 5c46c0bcf0
+274 -81
View File
@@ -4,9 +4,8 @@ import asyncio
import pymysql import pymysql
import time import time
import html import html
import httpx
from datetime import datetime, timezone, timedelta from datetime import datetime, timezone, timedelta
from telegram import Bot, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.error import TelegramError, RetryAfter, TimedOut
from dotenv import load_dotenv from dotenv import load_dotenv
from formatter import get_event_text from formatter import get_event_text
@@ -61,6 +60,13 @@ file_handler = RetryFileHandler(LOG_FILE, encoding='utf-8')
file_handler.setFormatter(formatter) file_handler.setFormatter(formatter)
logger.addHandler(file_handler) logger.addHandler(file_handler)
# Класс для обработки RetryAfter (FloodWait 429)
class RetryAfterException(Exception):
"""Исключение для обработки FloodWait (429) от Telegram API"""
def __init__(self, retry_after):
self.retry_after = retry_after
super().__init__(f"RetryAfter: {retry_after}")
def format_tags(tags_str): def format_tags(tags_str):
"""Форматирование тегов с добавлением #""" """Форматирование тегов с добавлением #"""
if not tags_str: if not tags_str:
@@ -84,7 +90,7 @@ def prepare_text(text):
return text return text
async def tg_post_event(bot, event_data): async def tg_post_event(httpx_client, event_data):
"""Публикация одного события""" """Публикация одного события"""
try: try:
# Форматирование текста # Форматирование текста
@@ -148,18 +154,48 @@ async def tg_post_event(bot, event_data):
logger.info(f"Текст для публикации: {initial_text[:200]}..." if len(initial_text) > 200 else f"Текст для публикации: {initial_text}") logger.info(f"Текст для публикации: {initial_text[:200]}..." if len(initial_text) > 200 else f"Текст для публикации: {initial_text}")
# Публикация первоначального сообщения без ссылок # Публикация первоначального сообщения без ссылок
send_photo_url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendPhoto"
send_message_url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
if has_image: if has_image:
try: try:
logger.info(f"Попытка отправки фото для события {event_data['number']}: chat_id={CHANNEL_ID}, caption_length={len(initial_text)}, image_url_length={len(image_url)}") logger.info(f"Попытка отправки фото для события {event_data['number']}: chat_id={CHANNEL_ID}, caption_length={len(initial_text)}, image_url_length={len(image_url)}")
message = await bot.send_photo( photo_payload = {
chat_id=CHANNEL_ID, 'chat_id': CHANNEL_ID,
photo=image_url, 'photo': image_url,
caption=initial_text, 'caption': initial_text,
parse_mode="HTML", 'parse_mode': 'HTML',
disable_notification=PUBLISH_SILENTLY 'disable_notification': PUBLISH_SILENTLY
) }
logger.info(f"Фото успешно отправлено для события {event_data['number']}, message_id={message.message_id}") photo_response = await httpx_client.post(send_photo_url, json=photo_payload)
except TimedOut as e:
if photo_response.status_code == 200:
photo_result = photo_response.json()
if photo_result.get('ok'):
message_data = photo_result.get('result', {})
message_id = message_data.get('message_id')
logger.info(f"Фото успешно отправлено для события {event_data['number']}, message_id={message_id}")
else:
# Ошибка в ответе API - пробуем отправить текстовое сообщение
error_code = photo_result.get('error_code')
if error_code == 429:
# FloodWait - пробрасываем как RetryAfter
retry_after = photo_result.get('parameters', {}).get('retry_after', 60)
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"API error: {photo_result.get('description', 'Unknown error')}")
else:
if photo_response.status_code == 429:
# FloodWait
retry_after = 60
try:
error_data = photo_response.json()
retry_after = error_data.get('parameters', {}).get('retry_after', 60)
except:
pass
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"HTTP {photo_response.status_code}: {photo_response.text}")
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при отправке изображения для события номер {event_data['number']}") logger.error(f"ТАЙМАУТ при отправке изображения для события номер {event_data['number']}")
logger.error(f"Полная диагностическая информация об ошибке TimedOut:") logger.error(f"Полная диагностическая информация об ошибке TimedOut:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
@@ -172,24 +208,51 @@ async def tg_post_event(bot, event_data):
logger.error(f" caption_length: {len(initial_text)}") logger.error(f" caption_length: {len(initial_text)}")
logger.error(f" parse_mode: HTML") logger.error(f" parse_mode: HTML")
raise raise
except TelegramError as e: except Exception as e:
error_msg = str(e)
if error_msg.startswith("RetryAfter:"):
retry_after = int(error_msg.split(":")[1])
raise Exception(f"RetryAfter:{retry_after}")
logger.warning(f"Не удалось отправить изображение для события номер {event_data['number']}: {e}. Отправляем текстовое сообщение.") logger.warning(f"Не удалось отправить изображение для события номер {event_data['number']}: {e}. Отправляем текстовое сообщение.")
logger.error(f"Полная информация об ошибке Telegram при отправке изображения для события {event_data['number']}:") logger.error(f"Полная информация об ошибке Telegram при отправке изображения для события {event_data['number']}:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
logger.error(f" Сообщение: {str(e)}") logger.error(f" Сообщение: {str(e)}")
logger.error(f" Все атрибуты ошибки: {vars(e)}") logger.error(f" Все атрибуты ошибки: {vars(e) if hasattr(e, '__dict__') else 'N/A'}")
logger.error(f" Полное представление: {repr(e)}") logger.error(f" Полное представление: {repr(e)}")
logger.info(f"Попытка отправки текстового сообщения вместо фото для события {event_data['number']}") logger.info(f"Попытка отправки текстового сообщения вместо фото для события {event_data['number']}")
try: try:
message = await bot.send_message( text_payload = {
chat_id=CHANNEL_ID, 'chat_id': CHANNEL_ID,
text=initial_text, 'text': initial_text,
parse_mode="HTML", 'parse_mode': 'HTML',
disable_notification=PUBLISH_SILENTLY, 'disable_notification': PUBLISH_SILENTLY,
disable_web_page_preview=True # Отключаем предпросмотр ссылок 'disable_web_page_preview': True
) }
logger.info(f"Текстовое сообщение успешно отправлено для события {event_data['number']}, message_id={message.message_id}") text_response = await httpx_client.post(send_message_url, json=text_payload)
except TimedOut as e:
if text_response.status_code == 200:
text_result = text_response.json()
if text_result.get('ok'):
message_data = text_result.get('result', {})
message_id = message_data.get('message_id')
logger.info(f"Текстовое сообщение успешно отправлено для события {event_data['number']}, message_id={message_id}")
else:
error_code = text_result.get('error_code')
if error_code == 429:
retry_after = text_result.get('parameters', {}).get('retry_after', 60)
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"API error: {text_result.get('description', 'Unknown error')}")
else:
if text_response.status_code == 429:
retry_after = 60
try:
error_data = text_response.json()
retry_after = error_data.get('parameters', {}).get('retry_after', 60)
except:
pass
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"HTTP {text_response.status_code}: {text_response.text}")
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при отправке текстового сообщения для события номер {event_data['number']}") logger.error(f"ТАЙМАУТ при отправке текстового сообщения для события номер {event_data['number']}")
logger.error(f"Полная диагностическая информация об ошибке TimedOut:") logger.error(f"Полная диагностическая информация об ошибке TimedOut:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
@@ -201,18 +264,46 @@ async def tg_post_event(bot, event_data):
logger.error(f" text_length: {len(initial_text)}") logger.error(f" text_length: {len(initial_text)}")
logger.error(f" parse_mode: HTML") logger.error(f" parse_mode: HTML")
raise raise
except Exception as e:
error_msg = str(e)
if error_msg.startswith("RetryAfter:"):
raise
raise
else: else:
logger.info(f"Попытка отправки текстового сообщения для события {event_data['number']}: chat_id={CHANNEL_ID}, text_length={len(initial_text)}") logger.info(f"Попытка отправки текстового сообщения для события {event_data['number']}: chat_id={CHANNEL_ID}, text_length={len(initial_text)}")
try: try:
message = await bot.send_message( text_payload = {
chat_id=CHANNEL_ID, 'chat_id': CHANNEL_ID,
text=initial_text, 'text': initial_text,
parse_mode="HTML", 'parse_mode': 'HTML',
disable_notification=PUBLISH_SILENTLY, 'disable_notification': PUBLISH_SILENTLY,
disable_web_page_preview=True # Отключаем предпросмотр ссылок 'disable_web_page_preview': True
) }
logger.info(f"Текстовое сообщение успешно отправлено для события {event_data['number']}, message_id={message.message_id}") text_response = await httpx_client.post(send_message_url, json=text_payload)
except TimedOut as e:
if text_response.status_code == 200:
text_result = text_response.json()
if text_result.get('ok'):
message_data = text_result.get('result', {})
message_id = message_data.get('message_id')
logger.info(f"Текстовое сообщение успешно отправлено для события {event_data['number']}, message_id={message_id}")
else:
error_code = text_result.get('error_code')
if error_code == 429:
retry_after = text_result.get('parameters', {}).get('retry_after', 60)
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"API error: {text_result.get('description', 'Unknown error')}")
else:
if text_response.status_code == 429:
retry_after = 60
try:
error_data = text_response.json()
retry_after = error_data.get('parameters', {}).get('retry_after', 60)
except:
pass
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"HTTP {text_response.status_code}: {text_response.text}")
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при отправке текстового сообщения для события номер {event_data['number']}") logger.error(f"ТАЙМАУТ при отправке текстового сообщения для события номер {event_data['number']}")
logger.error(f"Полная диагностическая информация об ошибке TimedOut:") logger.error(f"Полная диагностическая информация об ошибке TimedOut:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
@@ -225,9 +316,6 @@ async def tg_post_event(bot, event_data):
logger.error(f" parse_mode: HTML") logger.error(f" parse_mode: HTML")
raise raise
# Получаем ID сообщения для использования в ссылке подписки
message_id = message.message_id
# Формируем финальный текст с ссылками # Формируем финальный текст с ссылками
if USE_SUBSCRIPTION_BOT: if USE_SUBSCRIPTION_BOT:
links_line = f'🔎 <a href="{DESC_PREFIX}{number}/">Инфо</a> | 📌 <a href="{PZK_PREFIX}{number}/">Иду</a> | 🔜 <a href="https://t.me/{RESPONDER_BOT_NAME}?start=event_{message_id}">Подписка</a>' links_line = f'🔎 <a href="{DESC_PREFIX}{number}/">Инфо</a> | 📌 <a href="{PZK_PREFIX}{number}/">Иду</a> | 🔜 <a href="https://t.me/{RESPONDER_BOT_NAME}?start=event_{message_id}">Подписка</a>'
@@ -239,16 +327,42 @@ async def tg_post_event(bot, event_data):
# Редактируем сообщение, добавляя ссылки # Редактируем сообщение, добавляя ссылки
logger.info(f"Попытка редактирования сообщения для события {event_data['number']}: message_id={message_id}, final_text_length={len(final_text)}") logger.info(f"Попытка редактирования сообщения для события {event_data['number']}: message_id={message_id}, final_text_length={len(final_text)}")
edit_caption_url = f"https://api.telegram.org/bot{BOT_TOKEN}/editMessageCaption"
edit_text_url = f"https://api.telegram.org/bot{BOT_TOKEN}/editMessageText"
if has_image: if has_image:
try: try:
await bot.edit_message_caption( edit_caption_payload = {
chat_id=CHANNEL_ID, 'chat_id': CHANNEL_ID,
message_id=message_id, 'message_id': message_id,
caption=final_text, 'caption': final_text,
parse_mode="HTML" 'parse_mode': 'HTML'
) }
edit_caption_response = await httpx_client.post(edit_caption_url, json=edit_caption_payload)
if edit_caption_response.status_code == 200:
edit_result = edit_caption_response.json()
if edit_result.get('ok'):
logger.info(f"Подпись успешно отредактирована для события {event_data['number']}") logger.info(f"Подпись успешно отредактирована для события {event_data['number']}")
except TimedOut as e: else:
# Ошибка при редактировании подписи - пробуем редактировать текст
error_code = edit_result.get('error_code')
if error_code == 429:
retry_after = edit_result.get('parameters', {}).get('retry_after', 60)
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}")
else:
if edit_caption_response.status_code == 429:
retry_after = 60
try:
error_data = edit_caption_response.json()
retry_after = error_data.get('parameters', {}).get('retry_after', 60)
except:
pass
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"HTTP {edit_caption_response.status_code}: {edit_caption_response.text}")
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при редактировании подписи для события номер {event_data['number']}") logger.error(f"ТАЙМАУТ при редактировании подписи для события номер {event_data['number']}")
logger.error(f"Полная диагностическая информация об ошибке TimedOut:") logger.error(f"Полная диагностическая информация об ошибке TimedOut:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
@@ -261,24 +375,48 @@ async def tg_post_event(bot, event_data):
logger.error(f" caption_length: {len(final_text)}") logger.error(f" caption_length: {len(final_text)}")
logger.error(f" parse_mode: HTML") logger.error(f" parse_mode: HTML")
raise raise
except TelegramError as e: except Exception as e:
error_msg = str(e)
if error_msg.startswith("RetryAfter:"):
raise
logger.warning(f"Не удалось отредактировать подпись для события номер {event_data['number']}: {e}. Пробуем отредактировать текстовое сообщение.") logger.warning(f"Не удалось отредактировать подпись для события номер {event_data['number']}: {e}. Пробуем отредактировать текстовое сообщение.")
logger.error(f"Полная информация об ошибке Telegram при редактировании подписи для события {event_data['number']}:") logger.error(f"Полная информация об ошибке Telegram при редактировании подписи для события {event_data['number']}:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
logger.error(f" Сообщение: {str(e)}") logger.error(f" Сообщение: {str(e)}")
logger.error(f" Все атрибуты ошибки: {vars(e)}") logger.error(f" Все атрибуты ошибки: {vars(e) if hasattr(e, '__dict__') else 'N/A'}")
logger.error(f" Полное представление: {repr(e)}") logger.error(f" Полное представление: {repr(e)}")
logger.info(f"Попытка редактирования текста вместо подписи для события {event_data['number']}") logger.info(f"Попытка редактирования текста вместо подписи для события {event_data['number']}")
try: try:
await bot.edit_message_text( edit_text_payload = {
chat_id=CHANNEL_ID, 'chat_id': CHANNEL_ID,
message_id=message_id, 'message_id': message_id,
text=final_text, 'text': final_text,
parse_mode="HTML", 'parse_mode': 'HTML',
disable_web_page_preview=True # Отключаем предпросмотр ссылок 'disable_web_page_preview': True
) }
edit_text_response = await httpx_client.post(edit_text_url, json=edit_text_payload)
if edit_text_response.status_code == 200:
edit_result = edit_text_response.json()
if edit_result.get('ok'):
logger.info(f"Текст успешно отредактирован для события {event_data['number']}") logger.info(f"Текст успешно отредактирован для события {event_data['number']}")
except TimedOut as e: else:
error_code = edit_result.get('error_code')
if error_code == 429:
retry_after = edit_result.get('parameters', {}).get('retry_after', 60)
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}")
else:
if edit_text_response.status_code == 429:
retry_after = 60
try:
error_data = edit_text_response.json()
retry_after = error_data.get('parameters', {}).get('retry_after', 60)
except:
pass
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"HTTP {edit_text_response.status_code}: {edit_text_response.text}")
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при редактировании текста для события номер {event_data['number']}") logger.error(f"ТАЙМАУТ при редактировании текста для события номер {event_data['number']}")
logger.error(f"Полная диагностическая информация об ошибке TimedOut:") logger.error(f"Полная диагностическая информация об ошибке TimedOut:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
@@ -291,17 +429,43 @@ async def tg_post_event(bot, event_data):
logger.error(f" text_length: {len(final_text)}") logger.error(f" text_length: {len(final_text)}")
logger.error(f" parse_mode: HTML") logger.error(f" parse_mode: HTML")
raise raise
except Exception as e:
error_msg = str(e)
if error_msg.startswith("RetryAfter:"):
raise
raise
else: else:
try: try:
await bot.edit_message_text( edit_text_payload = {
chat_id=CHANNEL_ID, 'chat_id': CHANNEL_ID,
message_id=message_id, 'message_id': message_id,
text=final_text, 'text': final_text,
parse_mode="HTML", 'parse_mode': 'HTML',
disable_web_page_preview=True # Отключаем предпросмотр ссылок 'disable_web_page_preview': True
) }
edit_text_response = await httpx_client.post(edit_text_url, json=edit_text_payload)
if edit_text_response.status_code == 200:
edit_result = edit_text_response.json()
if edit_result.get('ok'):
logger.info(f"Текст успешно отредактирован для события {event_data['number']}") logger.info(f"Текст успешно отредактирован для события {event_data['number']}")
except TimedOut as e: else:
error_code = edit_result.get('error_code')
if error_code == 429:
retry_after = edit_result.get('parameters', {}).get('retry_after', 60)
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}")
else:
if edit_text_response.status_code == 429:
retry_after = 60
try:
error_data = edit_text_response.json()
retry_after = error_data.get('parameters', {}).get('retry_after', 60)
except:
pass
raise Exception(f"RetryAfter:{retry_after}")
raise Exception(f"HTTP {edit_text_response.status_code}: {edit_text_response.text}")
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при редактировании текста для события номер {event_data['number']}") logger.error(f"ТАЙМАУТ при редактировании текста для события номер {event_data['number']}")
logger.error(f"Полная диагностическая информация об ошибке TimedOut:") logger.error(f"Полная диагностическая информация об ошибке TimedOut:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
@@ -317,17 +481,7 @@ async def tg_post_event(bot, event_data):
return message_id # Возвращаем только message_id return message_id # Возвращаем только message_id
except RetryAfter as e: except httpx.TimeoutException as e:
# Обработка ошибки FloodWait (429)
logger.error(f"Получена ошибка FloodWait (429) при публикации события номер {event_data['number']}: {e}")
logger.error(f"Необходимо подождать {e.retry_after} секунд перед следующей попыткой")
logger.error(f"Полная информация об ошибке RetryAfter для события {event_data['number']}:")
logger.error(f" Тип ошибки: {type(e).__name__}")
logger.error(f" Сообщение: {str(e)}")
logger.error(f" Все атрибуты ошибки: {vars(e)}")
logger.error(f" Полное представление: {repr(e)}")
raise # Пробрасываем исключение выше для обработки на уровне цикла
except TimedOut as e:
logger.error(f"ТАЙМАУТ при публикации события номер {event_data['number']}") logger.error(f"ТАЙМАУТ при публикации события номер {event_data['number']}")
logger.error(f"Полная диагностическая информация об ошибке TimedOut:") logger.error(f"Полная диагностическая информация об ошибке TimedOut:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
@@ -341,12 +495,23 @@ async def tg_post_event(bot, event_data):
logger.error(f" initial_text_length: {len(initial_text) if 'initial_text' in locals() else 'N/A'}") logger.error(f" initial_text_length: {len(initial_text) if 'initial_text' in locals() else 'N/A'}")
logger.error(f" final_text_length: {len(final_text) if 'final_text' in locals() else 'N/A'}") logger.error(f" final_text_length: {len(final_text) if 'final_text' in locals() else 'N/A'}")
return None return None
except TelegramError as e: except Exception as e:
error_msg = str(e)
if error_msg.startswith("RetryAfter:"):
# Обработка ошибки FloodWait (429)
retry_after = int(error_msg.split(":")[1])
logger.error(f"Получена ошибка FloodWait (429) при публикации события номер {event_data['number']}")
logger.error(f"Необходимо подождать {retry_after} секунд перед следующей попыткой")
logger.error(f"Полная информация об ошибке RetryAfter для события {event_data['number']}:")
logger.error(f" Тип ошибки: RetryAfter")
logger.error(f" Сообщение: {error_msg}")
logger.error(f" retry_after: {retry_after}")
raise RetryAfterException(retry_after)
logger.error(f"Ошибка Telegram при публикации события номер {event_data['number']}: {e}") logger.error(f"Ошибка Telegram при публикации события номер {event_data['number']}: {e}")
logger.error(f"Полная информация об ошибке Telegram для события {event_data['number']}:") logger.error(f"Полная информация об ошибке Telegram для события {event_data['number']}:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
logger.error(f" Сообщение: {str(e)}") logger.error(f" Сообщение: {str(e)}")
logger.error(f" Все атрибуты ошибки: {vars(e)}") logger.error(f" Все атрибуты ошибки: {vars(e) if hasattr(e, '__dict__') else 'N/A'}")
logger.error(f" Полное представление: {repr(e)}") logger.error(f" Полное представление: {repr(e)}")
return None return None
except Exception as e: except Exception as e:
@@ -402,8 +567,16 @@ async def tg_post_event_by_id(id_event):
return return
old_message_id = event.get('tg_message_id') # Сохраняем старый ID сообщения old_message_id = event.get('tg_message_id') # Сохраняем старый ID сообщения
bot = Bot(token=BOT_TOKEN) # Создаем httpx клиент с отключенным HTTP/2
tg_message_id = await tg_post_event(bot, event) # Получаем новый message_id httpx_client = httpx.AsyncClient(
http2=False,
timeout=20.0,
follow_redirects=True
)
try:
tg_message_id = await tg_post_event(httpx_client, event) # Получаем новый message_id
finally:
await httpx_client.aclose()
if tg_message_id: if tg_message_id:
# Используем UTC время для записи в базу данных # Используем UTC время для записи в базу данных
@@ -430,13 +603,25 @@ async def tg_post_event_by_id(id_event):
else: else:
logger.error(f"Не удалось опубликовать событие ID {id_event}") logger.error(f"Не удалось опубликовать событие ID {id_event}")
except RetryAfter as e: except Exception as e:
# Проверяем, не RetryAfter ли это
error_msg = str(e)
if error_msg.startswith("RetryAfter:") or (hasattr(e, 'retry_after')):
retry_after = getattr(e, 'retry_after', int(error_msg.split(":")[1]) if ":" in error_msg else 60)
logger.error(f"Полная информация об ошибке RetryAfter в tg_post_event_by_id для события ID {id_event}:") logger.error(f"Полная информация об ошибке RetryAfter в tg_post_event_by_id для события ID {id_event}:")
logger.error(f" Тип ошибки: RetryAfter")
logger.error(f" Сообщение: {error_msg}")
logger.error(f" retry_after: {retry_after}")
logger.error(f" Полное представление: {repr(e)}")
raise RetryAfterException(retry_after)
# Если это не RetryAfter, обрабатываем как обычную ошибку
if "RetryAfter" not in error_msg:
logger.error(f"Ошибка при публикации: {e}")
logger.error(f"Полная информация об ошибке в tg_post_event_by_id для события ID {id_event}:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: {type(e).__name__}")
logger.error(f" Сообщение: {str(e)}") logger.error(f" Сообщение: {str(e)}")
logger.error(f" Все атрибуты ошибки: {vars(e)}") logger.error(f" Все атрибуты ошибки: {vars(e) if hasattr(e, '__dict__') else 'N/A'}")
logger.error(f" Полное представление: {repr(e)}") logger.error(f" Полное представление: {repr(e)}")
raise e
except Exception as e: except Exception as e:
logger.error(f"Ошибка при публикации: {e}") logger.error(f"Ошибка при публикации: {e}")
logger.error(f"Полная информация об ошибке в tg_post_event_by_id для события ID {id_event}:") logger.error(f"Полная информация об ошибке в tg_post_event_by_id для события ID {id_event}:")
@@ -497,14 +682,22 @@ async def tg_post_all_events():
if event_count < len(events): if event_count < len(events):
await asyncio.sleep(2) await asyncio.sleep(2)
except RetryAfter as e: except RetryAfterException as e:
logger.error(f"Прерываем публикацию из-за ошибки FloodWait. Ожидание: {e.retry_after} секунд") logger.error(f"Прерываем публикацию из-за ошибки FloodWait. Ожидание: {e.retry_after} секунд")
logger.error(f"Полная информация об ошибке RetryAfter в tg_post_all_events для события ID {event['id_event']}:") logger.error(f"Полная информация об ошибке RetryAfter в tg_post_all_events для события ID {event['id_event']}:")
logger.error(f" Тип ошибки: {type(e).__name__}") logger.error(f" Тип ошибки: RetryAfter")
logger.error(f" Сообщение: {str(e)}") logger.error(f" Сообщение: {str(e)}")
logger.error(f" Все атрибуты ошибки: {vars(e)}") logger.error(f" retry_after: {e.retry_after}")
logger.error(f" Полное представление: {repr(e)}") logger.error(f" Полное представление: {repr(e)}")
break break
except Exception as e:
logger.error(f"Ошибка при публикации события ID {event['id_event']}: {e}")
logger.error(f"Полная информация об ошибке в tg_post_all_events для события ID {event['id_event']}:")
logger.error(f" Тип ошибки: {type(e).__name__}")
logger.error(f" Сообщение: {str(e)}")
logger.error(f" Все атрибуты ошибки: {vars(e) if hasattr(e, '__dict__') else 'N/A'}")
logger.error(f" Полное представление: {repr(e)}")
# Продолжаем публикацию следующих событий, несмотря на ошибку
except Exception as e: except Exception as e:
logger.error(f"Ошибка при публикации события ID {event['id_event']}: {e}") logger.error(f"Ошибка при публикации события ID {event['id_event']}: {e}")
logger.error(f"Полная информация об ошибке в tg_post_all_events для события ID {event['id_event']}:") logger.error(f"Полная информация об ошибке в tg_post_all_events для события ID {event['id_event']}:")