From 69fc6d9c1e82ec87ec08765f10e92e8d08029851 Mon Sep 17 00:00:00 2001 From: QifengKuang Date: Mon, 4 May 2026 04:54:18 -0700 Subject: [PATCH] fix(telegram): fall back to document on any send_photo failure, not just dim errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Broadens the existing fallback (previously only fired for Photo_invalid_dimensions) to cover every send_photo exception class: rate limits, corrupt file markers, format edge cases. The expected dimension case still logs at INFO (document is the right path); all other cases log at WARNING with exc_info so they're visible in logs. If send_document itself fails, we still fall back to the base adapter's text-only 'Image: /path' rendering as a last resort. Salvage of #15837 — original PR author QifengKuang proposed the broader try/except-style fallback. Adapted to keep the existing INFO-vs-WARNING log split for dimension errors (the expected case). Co-authored-by: QifengKuang --- gateway/platforms/telegram.py | 46 ++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/gateway/platforms/telegram.py b/gateway/platforms/telegram.py index 247b5fbb93..167d47237e 100644 --- a/gateway/platforms/telegram.py +++ b/gateway/platforms/telegram.py @@ -2268,14 +2268,36 @@ class TelegramAdapter(BasePlatformAdapter): return SendResult(success=True, message_id=str(msg.message_id)) except Exception as e: error_str = str(e) - # Check for dimension-related errors - fallback to document mode - if "Photo_invalid_dimensions" in error_str or "PHOTO_INVALID_DIMENSIONS" in error_str: + # Dimension-related errors are the expected case for valid image + # files that Telegram just refuses as photos (screenshots, extreme + # aspect ratios). Log at INFO because the document fallback is + # the correct path. Any other send_photo failure also falls back + # to document (rate limits, corrupt file markers, format edge + # cases), but at WARNING because it's unexpected and worth + # surfacing in logs. + is_dim_error = ( + "Photo_invalid_dimensions" in error_str + or "PHOTO_INVALID_DIMENSIONS" in error_str + ) + if is_dim_error: logger.info( - "[%s] Image dimensions exceed Telegram photo limits, sending as document: %s", + "[%s] Image dimensions exceed Telegram photo limits, " + "sending as document: %s", self.name, image_path, ) - # Fallback to sending as document (file) - no dimension limits, only 50MB size limit + else: + logger.warning( + "[%s] Failed to send Telegram local image as photo, " + "trying document fallback: %s", + self.name, + e, + exc_info=True, + ) + # Fallback to sending as document (file) — no dimension limit, + # only 50MB size limit. If even that fails, fall back to the + # base adapter's text-only "Image: /path" rendering. + try: return await self.send_document( chat_id=chat_id, file_path=image_path, @@ -2284,13 +2306,15 @@ class TelegramAdapter(BasePlatformAdapter): reply_to=reply_to, metadata=metadata, ) - logger.error( - "[%s] Failed to send Telegram local image, falling back to base adapter: %s", - self.name, - e, - exc_info=True, - ) - return await super().send_image_file(chat_id, image_path, caption, reply_to) + except Exception as doc_err: + logger.error( + "[%s] Failed to send Telegram local image as document, " + "falling back to base adapter: %s", + self.name, + doc_err, + exc_info=True, + ) + return await super().send_image_file(chat_id, image_path, caption, reply_to) async def send_document( self,