[ВОЛК] детальный лог телего-ошибок в tg_publish
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-01-10 14:21:51 +03:00
parent a5705b2ceb
commit d908c28b5d
+62 -7
View File
@@ -88,6 +88,22 @@ def has_org_tag(text):
pattern = r'#?' + re.escape(ORG_MESSAGE_TAG) + r'\b' pattern = r'#?' + re.escape(ORG_MESSAGE_TAG) + r'\b'
return bool(re.search(pattern, text, re.IGNORECASE)) return bool(re.search(pattern, text, re.IGNORECASE))
def log_telegram_error(response, context=""):
"""Логирует полную информацию об ошибке от Telegram API"""
try:
if response is not None:
logger.error(f"{context} Статус код: {response.status_code}")
logger.error(f"{context} Заголовки ответа: {dict(response.headers)}")
try:
error_data = response.json()
logger.error(f"{context} Полный ответ от Telegram API: {json.dumps(error_data, ensure_ascii=False, indent=2)}")
except:
logger.error(f"{context} Текст ответа: {response.text}")
else:
logger.error(f"{context} Ответ от Telegram API отсутствует (None)")
except Exception as e:
logger.error(f"{context} Ошибка при логировании информации об ошибке: {e}")
async def publish_to_tg(vk_post_id): async def publish_to_tg(vk_post_id):
"""Публикация одной записи по VK post ID""" """Публикация одной записи по VK post ID"""
logger.info(f"Запуск публикации для записи VK ID {vk_post_id}") logger.info(f"Запуск публикации для записи VK ID {vk_post_id}")
@@ -124,6 +140,10 @@ async def publish_to_tg(vk_post_id):
follow_redirects=True follow_redirects=True
) )
# Переменная для отслеживания успешности публикации
message_id = None
publication_successful = False
try: try:
# Проверяем наличие организационного хештега # Проверяем наличие организационного хештега
is_org_message = has_org_tag(post['text']) is_org_message = has_org_tag(post['text'])
@@ -193,13 +213,15 @@ async def publish_to_tg(vk_post_id):
message_data = photo_result.get('result', {}) message_data = photo_result.get('result', {})
message_id = message_data.get('message_id') message_id = message_data.get('message_id')
else: else:
# Ошибка в ответе API - пробуем отправить текстовое сообщение # Ошибка в ответе API - логируем полную информацию
log_telegram_error(photo_response, f"[Отправка фото для VK ID {vk_post_id}]")
error_code = photo_result.get('error_code') error_code = photo_result.get('error_code')
if error_code == 429: if error_code == 429:
retry_after = photo_result.get('parameters', {}).get('retry_after', 60) retry_after = photo_result.get('parameters', {}).get('retry_after', 60)
raise RetryAfterException(retry_after) raise RetryAfterException(retry_after)
raise Exception(f"API error: {photo_result.get('description', 'Unknown error')}") raise Exception(f"API error: {photo_result.get('description', 'Unknown error')}")
else: else:
log_telegram_error(photo_response, f"[Отправка фото для VK ID {vk_post_id}]")
if photo_response.status_code == 429: if photo_response.status_code == 429:
retry_after = 60 retry_after = 60
try: try:
@@ -211,6 +233,10 @@ async def publish_to_tg(vk_post_id):
raise Exception(f"HTTP {photo_response.status_code}: {photo_response.text}") raise Exception(f"HTTP {photo_response.status_code}: {photo_response.text}")
except RetryAfterException: except RetryAfterException:
raise raise
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при отправке изображения для записи VK ID {vk_post_id}")
logger.error(f"Детали таймаута: {type(e).__name__}: {e}")
raise # Пробрасываем таймаут наверх
except Exception as e: except Exception as e:
logger.warning(f"Не удалось отправить изображение для записи VK ID {vk_post_id}: {e}. Отправляем текстовое сообщение.") logger.warning(f"Не удалось отправить изображение для записи VK ID {vk_post_id}: {e}. Отправляем текстовое сообщение.")
text_payload = { text_payload = {
@@ -228,12 +254,14 @@ async def publish_to_tg(vk_post_id):
message_data = text_result.get('result', {}) message_data = text_result.get('result', {})
message_id = message_data.get('message_id') message_id = message_data.get('message_id')
else: else:
log_telegram_error(text_response, f"[Отправка текста (fallback) для VK ID {vk_post_id}]")
error_code = text_result.get('error_code') error_code = text_result.get('error_code')
if error_code == 429: if error_code == 429:
retry_after = text_result.get('parameters', {}).get('retry_after', 60) retry_after = text_result.get('parameters', {}).get('retry_after', 60)
raise RetryAfterException(retry_after) raise RetryAfterException(retry_after)
raise Exception(f"API error: {text_result.get('description', 'Unknown error')}") raise Exception(f"API error: {text_result.get('description', 'Unknown error')}")
else: else:
log_telegram_error(text_response, f"[Отправка текста (fallback) для VK ID {vk_post_id}]")
if text_response.status_code == 429: if text_response.status_code == 429:
retry_after = 60 retry_after = 60
try: try:
@@ -260,12 +288,14 @@ async def publish_to_tg(vk_post_id):
message_data = text_result.get('result', {}) message_data = text_result.get('result', {})
message_id = message_data.get('message_id') message_id = message_data.get('message_id')
else: else:
log_telegram_error(text_response, f"[Отправка текста для VK ID {vk_post_id}]")
error_code = text_result.get('error_code') error_code = text_result.get('error_code')
if error_code == 429: if error_code == 429:
retry_after = text_result.get('parameters', {}).get('retry_after', 60) retry_after = text_result.get('parameters', {}).get('retry_after', 60)
raise RetryAfterException(retry_after) raise RetryAfterException(retry_after)
raise Exception(f"API error: {text_result.get('description', 'Unknown error')}") raise Exception(f"API error: {text_result.get('description', 'Unknown error')}")
else: else:
log_telegram_error(text_response, f"[Отправка текста для VK ID {vk_post_id}]")
if text_response.status_code == 429: if text_response.status_code == 429:
retry_after = 60 retry_after = 60
try: try:
@@ -308,12 +338,14 @@ async def publish_to_tg(vk_post_id):
if edit_caption_response.status_code == 200: if edit_caption_response.status_code == 200:
edit_result = edit_caption_response.json() edit_result = edit_caption_response.json()
if not edit_result.get('ok'): if not edit_result.get('ok'):
log_telegram_error(edit_caption_response, f"[Редактирование подписи для VK ID {vk_post_id}]")
error_code = edit_result.get('error_code') error_code = edit_result.get('error_code')
if error_code == 429: if error_code == 429:
retry_after = edit_result.get('parameters', {}).get('retry_after', 60) retry_after = edit_result.get('parameters', {}).get('retry_after', 60)
raise RetryAfterException(retry_after) raise RetryAfterException(retry_after)
raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}") raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}")
else: else:
log_telegram_error(edit_caption_response, f"[Редактирование подписи для VK ID {vk_post_id}]")
if edit_caption_response.status_code == 429: if edit_caption_response.status_code == 429:
retry_after = 60 retry_after = 60
try: try:
@@ -325,6 +357,10 @@ async def publish_to_tg(vk_post_id):
raise Exception(f"HTTP {edit_caption_response.status_code}: {edit_caption_response.text}") raise Exception(f"HTTP {edit_caption_response.status_code}: {edit_caption_response.text}")
except RetryAfterException: except RetryAfterException:
raise raise
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при редактировании подписи для записи VK ID {vk_post_id}")
logger.error(f"Детали таймаута: {type(e).__name__}: {e}")
raise # Пробрасываем таймаут наверх
except Exception as e: except Exception as e:
logger.warning(f"Не удалось отредактировать подпись для записи VK ID {vk_post_id}: {e}. Пробуем отредактировать текстовое сообщение.") logger.warning(f"Не удалось отредактировать подпись для записи VK ID {vk_post_id}: {e}. Пробуем отредактировать текстовое сообщение.")
edit_text_payload = { edit_text_payload = {
@@ -339,12 +375,14 @@ async def publish_to_tg(vk_post_id):
if edit_text_response.status_code == 200: if edit_text_response.status_code == 200:
edit_result = edit_text_response.json() edit_result = edit_text_response.json()
if not edit_result.get('ok'): if not edit_result.get('ok'):
log_telegram_error(edit_text_response, f"[Редактирование текста (fallback) для VK ID {vk_post_id}]")
error_code = edit_result.get('error_code') error_code = edit_result.get('error_code')
if error_code == 429: if error_code == 429:
retry_after = edit_result.get('parameters', {}).get('retry_after', 60) retry_after = edit_result.get('parameters', {}).get('retry_after', 60)
raise RetryAfterException(retry_after) raise RetryAfterException(retry_after)
raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}") raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}")
else: else:
log_telegram_error(edit_text_response, f"[Редактирование текста (fallback) для VK ID {vk_post_id}]")
if edit_text_response.status_code == 429: if edit_text_response.status_code == 429:
retry_after = 60 retry_after = 60
try: try:
@@ -367,12 +405,14 @@ async def publish_to_tg(vk_post_id):
if edit_text_response.status_code == 200: if edit_text_response.status_code == 200:
edit_result = edit_text_response.json() edit_result = edit_text_response.json()
if not edit_result.get('ok'): if not edit_result.get('ok'):
log_telegram_error(edit_text_response, f"[Редактирование текста для VK ID {vk_post_id}]")
error_code = edit_result.get('error_code') error_code = edit_result.get('error_code')
if error_code == 429: if error_code == 429:
retry_after = edit_result.get('parameters', {}).get('retry_after', 60) retry_after = edit_result.get('parameters', {}).get('retry_after', 60)
raise RetryAfterException(retry_after) raise RetryAfterException(retry_after)
raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}") raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}")
else: else:
log_telegram_error(edit_text_response, f"[Редактирование текста для VK ID {vk_post_id}]")
if edit_text_response.status_code == 429: if edit_text_response.status_code == 429:
retry_after = 60 retry_after = 60
try: try:
@@ -420,12 +460,14 @@ async def publish_to_tg(vk_post_id):
poll_message_id = poll_message_data.get('message_id') poll_message_id = poll_message_data.get('message_id')
logger.info(f"Опубликован опрос для записи VK ID {vk_post_id}") logger.info(f"Опубликован опрос для записи VK ID {vk_post_id}")
else: else:
log_telegram_error(poll_response, f"[Отправка опроса для VK ID {vk_post_id}]")
error_code = poll_result.get('error_code') error_code = poll_result.get('error_code')
if error_code == 429: if error_code == 429:
retry_after = poll_result.get('parameters', {}).get('retry_after', 60) retry_after = poll_result.get('parameters', {}).get('retry_after', 60)
raise RetryAfterException(retry_after) raise RetryAfterException(retry_after)
raise Exception(f"API error: {poll_result.get('description', 'Unknown error')}") raise Exception(f"API error: {poll_result.get('description', 'Unknown error')}")
else: else:
log_telegram_error(poll_response, f"[Отправка опроса для VK ID {vk_post_id}]")
if poll_response.status_code == 429: if poll_response.status_code == 429:
retry_after = 60 retry_after = 60
try: try:
@@ -438,10 +480,20 @@ async def publish_to_tg(vk_post_id):
except RetryAfterException: except RetryAfterException:
raise raise
except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при публикации опроса для записи VK ID {vk_post_id}")
logger.error(f"Детали таймаута: {type(e).__name__}: {e}")
raise # Пробрасываем таймаут наверх
except Exception as e: except Exception as e:
logger.error(f"Ошибка при публикации опроса для записи VK ID {vk_post_id}: {e}") logger.error(f"Ошибка при публикации опроса для записи VK ID {vk_post_id}: {e}")
# Обновляем запись в базе данных # Проверяем, что message_id был получен (публикация успешна)
if message_id is None:
logger.error(f"Не удалось получить message_id для записи VK ID {vk_post_id}. Публикация не завершена.")
return False
# Обновляем запись в базе данных только если публикация успешна
publication_successful = True
current_time_utc = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S") current_time_utc = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
cursor.execute(""" cursor.execute("""
UPDATE posts UPDATE posts
@@ -463,7 +515,11 @@ async def publish_to_tg(vk_post_id):
logger.error(f"Необходимо подождать {e.retry_after} секунд перед следующей попыткой") logger.error(f"Необходимо подождать {e.retry_after} секунд перед следующей попыткой")
raise raise
except httpx.TimeoutException as e: except httpx.TimeoutException as e:
logger.error(f"ТАЙМАУТ при публикации записи VK ID {vk_post_id}: {e}") logger.error(f"ТАЙМАУТ при публикации записи VK ID {vk_post_id}")
logger.error(f"Детали таймаута: {type(e).__name__}: {e}")
if hasattr(e, 'request'):
logger.error(f"Запрос, вызвавший таймаут: {e.request.method} {e.request.url if hasattr(e.request, 'url') else 'N/A'}")
# Убеждаемся, что БД не обновляется при таймауте
return False return False
except Exception as e: except Exception as e:
error_msg = str(e) error_msg = str(e)
@@ -472,10 +528,9 @@ async def publish_to_tg(vk_post_id):
logger.error(f"Получена ошибка FloodWait (429) при публикации записи VK ID {vk_post_id}") logger.error(f"Получена ошибка FloodWait (429) при публикации записи VK ID {vk_post_id}")
logger.error(f"Необходимо подождать {retry_after} секунд перед следующей попыткой") logger.error(f"Необходимо подождать {retry_after} секунд перед следующей попыткой")
raise RetryAfterException(retry_after) raise RetryAfterException(retry_after)
logger.error(f"Ошибка Telegram при публикации записи VK ID {vk_post_id}: {e}") logger.error(f"Ошибка Telegram при публикации записи VK ID {vk_post_id}: {type(e).__name__}: {e}")
return False logger.error(f"Детали ошибки: {repr(e)}")
except Exception as e: # Убеждаемся, что БД не обновляется при ошибке
logger.error(f"Неожиданная ошибка при публикации записи VK ID {vk_post_id}: {e}")
return False return False
finally: finally:
if conn: if conn: