Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 33 additions & 21 deletions astrbot/core/platform/sources/telegram/tg_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from contextlib import suppress
from typing import cast

from apscheduler.events import EVENT_JOB_ERROR
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from telegram import BotCommand, Update
from telegram.constants import ChatType
Expand Down Expand Up @@ -80,6 +81,12 @@ def __init__(
self.last_command_hash = None

self.scheduler = AsyncIOScheduler()
self.scheduler.add_listener(
lambda ev: logger.error(
"Scheduled job %s raised: %s", ev.job_id, ev.exception, exc_info=ev.exception
),
EVENT_JOB_ERROR,
)
Comment on lines +84 to +89
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While using a lambda for the error listener is functional, it's generally better practice to use a named method for event listeners in classes. This improves readability and makes it easier to manage the listener if needed in the future. Additionally, consider explicitly passing the traceback to exc_info using a tuple (type(ev.exception), ev.exception, ev.traceback) to ensure the stack trace is correctly captured, as APScheduler provides the traceback object specifically for this purpose.

Suggested change
self.scheduler.add_listener(
lambda ev: logger.error(
"Scheduled job %s raised: %s", ev.job_id, ev.exception, exc_info=ev.exception
),
EVENT_JOB_ERROR,
)
self.scheduler.add_listener(self._on_job_error, EVENT_JOB_ERROR)
self._terminating = False
self._loop: asyncio.AbstractEventLoop | None = None
self._polling_recovery_requested = asyncio.Event()
def _on_job_error(self, event):
logger.error(
"Scheduled job %s raised: %s",
event.job_id,
event.exception,
exc_info=(type(event.exception), event.exception, event.traceback)
)

self._terminating = False
self._loop: asyncio.AbstractEventLoop | None = None
self._polling_recovery_requested = asyncio.Event()
Expand Down Expand Up @@ -695,31 +702,36 @@ async def process_media_group(self, media_group_id: str) -> None:
f"Processing media group {media_group_id}, total {len(updates_and_contexts)} items"
)

# Use the first update to create the base message (with reply, caption, etc.)
first_update, first_context = updates_and_contexts[0]
abm = await self.convert_message(first_update, first_context)
try:
# Use the first update to create the base message (with reply, caption, etc.)
first_update, first_context = updates_and_contexts[0]
abm = await self.convert_message(first_update, first_context)

if not abm:
logger.warning(
f"Failed to convert the first message of media group {media_group_id}"
)
return
if not abm:
logger.warning(
f"Failed to convert the first message of media group {media_group_id}"
)
return

# Add additional media from remaining updates by reusing convert_message
for update, context in updates_and_contexts[1:]:
# Convert the message but skip reply chains (get_reply=False)
extra = await self.convert_message(update, context, get_reply=False)
if not extra:
continue
# Add additional media from remaining updates by reusing convert_message
for update, context in updates_and_contexts[1:]:
# Convert the message but skip reply chains (get_reply=False)
extra = await self.convert_message(update, context, get_reply=False)
if not extra:
continue

# Merge only the message components (keep base session/meta from first)
abm.message.extend(extra.message)
logger.debug(
f"Added {len(extra.message)} components to media group {media_group_id}"
)
# Merge only the message components (keep base session/meta from first)
abm.message.extend(extra.message)
logger.debug(
f"Added {len(extra.message)} components to media group {media_group_id}"
)

# Process the merged message
await self.handle_msg(abm)
# Process the merged message
await self.handle_msg(abm)
except Exception:
logger.error(
f"Failed to process media group {media_group_id}", exc_info=True
)

async def handle_msg(self, message: AstrBotMessage) -> None:
message_event = TelegramPlatformEvent(
Expand Down
Loading