Skip to content
Merged
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
22 changes: 22 additions & 0 deletions astrbot/core/platform/sources/weixin_oc/weixin_oc_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class WeixinOCReplyMeta:
support_streaming_message=False,
)
class WeixinOCAdapter(Platform):
SESSION_TIMEOUT_ERRCODE = -14
IMAGE_ITEM_TYPE = 2
VOICE_ITEM_TYPE = 3
FILE_ITEM_TYPE = 4
Expand Down Expand Up @@ -951,6 +952,23 @@ def _format_api_error(payload: dict[str, Any]) -> str:
errmsg = str(payload.get("errmsg", ""))
return f"ret={ret}, errcode={errcode}, errmsg={errmsg}"

@staticmethod
def _api_errcode(payload: dict[str, Any]) -> int:
return int(payload.get("errcode") or 0)

async def _handle_inbound_session_timeout(self) -> None:
logger.warning(
"weixin_oc(%s): session timed out, clearing login state and waiting for QR login.",
self.meta().id,
)
self.token = None
self.account_id = None
self._sync_buf = ""
self._context_tokens = {}
self._context_tokens_dirty = False
self._login_session = None
await self._save_account_state()
Comment on lines +959 to +970

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

When a session times out, it is important to clean up any active typing keepalive tasks. These tasks rely on the session and will continue to run and fail repeatedly if not stopped. Explicitly calling _cleanup_typing_tasks() ensures that these resources are released immediately.

Suggested change
async def _handle_inbound_session_timeout(self) -> None:
logger.warning(
"weixin_oc(%s): session timed out, clearing login state and waiting for QR login.",
self.meta().id,
)
self.token = None
self.account_id = None
self._sync_buf = ""
self._context_tokens = {}
self._context_tokens_dirty = False
self._login_session = None
await self._save_account_state()
async def _handle_inbound_session_timeout(self) -> None:
logger.warning(
"weixin_oc(%s): session timed out, clearing login state and waiting for QR login.",
self.meta().id,
)
await self._cleanup_typing_tasks()
self.token = None
self.account_id = None
self._sync_buf = ""
self._context_tokens = {}
self._context_tokens_dirty = False
self._login_session = None
await self._save_account_state()


async def _send_media_segment(
self,
user_id: str,
Expand Down Expand Up @@ -1566,6 +1584,10 @@ async def _poll_inbound_updates(self) -> None:
self.meta().id,
self._last_inbound_error,
)
if self._api_errcode(data) == self.SESSION_TIMEOUT_ERRCODE:
await self._handle_inbound_session_timeout()
return
await asyncio.sleep(5)
return

should_save_state = self._context_tokens_dirty
Expand Down
Loading