fix(telegram): fall back to document on any send_photo failure, not just dim errors

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 <k2767567815@gmail.com>
This commit is contained in:
QifengKuang 2026-05-04 04:54:18 -07:00 committed by Teknium
parent d3b22b76d8
commit 69fc6d9c1e

View file

@ -2268,14 +2268,36 @@ class TelegramAdapter(BasePlatformAdapter):
return SendResult(success=True, message_id=str(msg.message_id)) return SendResult(success=True, message_id=str(msg.message_id))
except Exception as e: except Exception as e:
error_str = str(e) error_str = str(e)
# Check for dimension-related errors - fallback to document mode # Dimension-related errors are the expected case for valid image
if "Photo_invalid_dimensions" in error_str or "PHOTO_INVALID_DIMENSIONS" in error_str: # 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( 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, self.name,
image_path, 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( return await self.send_document(
chat_id=chat_id, chat_id=chat_id,
file_path=image_path, file_path=image_path,
@ -2284,13 +2306,15 @@ class TelegramAdapter(BasePlatformAdapter):
reply_to=reply_to, reply_to=reply_to,
metadata=metadata, metadata=metadata,
) )
logger.error( except Exception as doc_err:
"[%s] Failed to send Telegram local image, falling back to base adapter: %s", logger.error(
self.name, "[%s] Failed to send Telegram local image as document, "
e, "falling back to base adapter: %s",
exc_info=True, self.name,
) doc_err,
return await super().send_image_file(chat_id, image_path, caption, reply_to) exc_info=True,
)
return await super().send_image_file(chat_id, image_path, caption, reply_to)
async def send_document( async def send_document(
self, self,