diff --git a/tg_publish.py b/tg_publish.py index 9d6b3ad..0829f46 100644 --- a/tg_publish.py +++ b/tg_publish.py @@ -88,6 +88,22 @@ def has_org_tag(text): pattern = r'#?' + re.escape(ORG_MESSAGE_TAG) + r'\b' 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): """Публикация одной записи по 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 ) + # Переменная для отслеживания успешности публикации + message_id = None + publication_successful = False + try: # Проверяем наличие организационного хештега 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_id = message_data.get('message_id') else: - # Ошибка в ответе API - пробуем отправить текстовое сообщение + # Ошибка в ответе API - логируем полную информацию + log_telegram_error(photo_response, f"[Отправка фото для VK ID {vk_post_id}]") error_code = photo_result.get('error_code') if error_code == 429: retry_after = photo_result.get('parameters', {}).get('retry_after', 60) raise RetryAfterException(retry_after) raise Exception(f"API error: {photo_result.get('description', 'Unknown error')}") else: + log_telegram_error(photo_response, f"[Отправка фото для VK ID {vk_post_id}]") if photo_response.status_code == 429: retry_after = 60 try: @@ -211,6 +233,10 @@ async def publish_to_tg(vk_post_id): raise Exception(f"HTTP {photo_response.status_code}: {photo_response.text}") except RetryAfterException: 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: logger.warning(f"Не удалось отправить изображение для записи VK ID {vk_post_id}: {e}. Отправляем текстовое сообщение.") text_payload = { @@ -228,12 +254,14 @@ async def publish_to_tg(vk_post_id): message_data = text_result.get('result', {}) message_id = message_data.get('message_id') else: + log_telegram_error(text_response, f"[Отправка текста (fallback) для VK ID {vk_post_id}]") error_code = text_result.get('error_code') if error_code == 429: retry_after = text_result.get('parameters', {}).get('retry_after', 60) raise RetryAfterException(retry_after) raise Exception(f"API error: {text_result.get('description', 'Unknown error')}") else: + log_telegram_error(text_response, f"[Отправка текста (fallback) для VK ID {vk_post_id}]") if text_response.status_code == 429: retry_after = 60 try: @@ -260,12 +288,14 @@ async def publish_to_tg(vk_post_id): message_data = text_result.get('result', {}) message_id = message_data.get('message_id') else: + log_telegram_error(text_response, f"[Отправка текста для VK ID {vk_post_id}]") error_code = text_result.get('error_code') if error_code == 429: retry_after = text_result.get('parameters', {}).get('retry_after', 60) raise RetryAfterException(retry_after) raise Exception(f"API error: {text_result.get('description', 'Unknown error')}") else: + log_telegram_error(text_response, f"[Отправка текста для VK ID {vk_post_id}]") if text_response.status_code == 429: retry_after = 60 try: @@ -308,12 +338,14 @@ async def publish_to_tg(vk_post_id): if edit_caption_response.status_code == 200: edit_result = edit_caption_response.json() 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') if error_code == 429: retry_after = edit_result.get('parameters', {}).get('retry_after', 60) raise RetryAfterException(retry_after) raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}") else: + log_telegram_error(edit_caption_response, f"[Редактирование подписи для VK ID {vk_post_id}]") if edit_caption_response.status_code == 429: retry_after = 60 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}") except RetryAfterException: 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: logger.warning(f"Не удалось отредактировать подпись для записи VK ID {vk_post_id}: {e}. Пробуем отредактировать текстовое сообщение.") edit_text_payload = { @@ -339,12 +375,14 @@ async def publish_to_tg(vk_post_id): if edit_text_response.status_code == 200: edit_result = edit_text_response.json() 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') if error_code == 429: retry_after = edit_result.get('parameters', {}).get('retry_after', 60) raise RetryAfterException(retry_after) raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}") else: + log_telegram_error(edit_text_response, f"[Редактирование текста (fallback) для VK ID {vk_post_id}]") if edit_text_response.status_code == 429: retry_after = 60 try: @@ -367,12 +405,14 @@ async def publish_to_tg(vk_post_id): if edit_text_response.status_code == 200: edit_result = edit_text_response.json() 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') if error_code == 429: retry_after = edit_result.get('parameters', {}).get('retry_after', 60) raise RetryAfterException(retry_after) raise Exception(f"API error: {edit_result.get('description', 'Unknown error')}") else: + log_telegram_error(edit_text_response, f"[Редактирование текста для VK ID {vk_post_id}]") if edit_text_response.status_code == 429: retry_after = 60 try: @@ -420,12 +460,14 @@ async def publish_to_tg(vk_post_id): poll_message_id = poll_message_data.get('message_id') logger.info(f"Опубликован опрос для записи VK ID {vk_post_id}") else: + log_telegram_error(poll_response, f"[Отправка опроса для VK ID {vk_post_id}]") error_code = poll_result.get('error_code') if error_code == 429: retry_after = poll_result.get('parameters', {}).get('retry_after', 60) raise RetryAfterException(retry_after) raise Exception(f"API error: {poll_result.get('description', 'Unknown error')}") else: + log_telegram_error(poll_response, f"[Отправка опроса для VK ID {vk_post_id}]") if poll_response.status_code == 429: retry_after = 60 try: @@ -438,10 +480,20 @@ async def publish_to_tg(vk_post_id): except RetryAfterException: 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: 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") cursor.execute(""" UPDATE posts @@ -463,7 +515,11 @@ async def publish_to_tg(vk_post_id): logger.error(f"Необходимо подождать {e.retry_after} секунд перед следующей попыткой") raise 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 except Exception as 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"Необходимо подождать {retry_after} секунд перед следующей попыткой") raise RetryAfterException(retry_after) - logger.error(f"Ошибка Telegram при публикации записи VK ID {vk_post_id}: {e}") - return False - except Exception as e: - logger.error(f"Неожиданная ошибка при публикации записи VK ID {vk_post_id}: {e}") + logger.error(f"Ошибка Telegram при публикации записи VK ID {vk_post_id}: {type(e).__name__}: {e}") + logger.error(f"Детали ошибки: {repr(e)}") + # Убеждаемся, что БД не обновляется при ошибке return False finally: if conn: