fix(weixin): retry on session/rate-limit errors in send_weixin_direct - #35065
fix(weixin): retry on session/rate-limit errors in send_weixin_direct#35065hanhan-tg wants to merge 1 commit into
Conversation
When send_weixin_direct() hits rate-limit errors (ret=-2) or session timeout errors (errcode=-14), it now retries once with a 3-second backoff after clearing the stale context_token, falling back to a tokenless send attempt. Fixes the silent delivery failure after gateway restart where stale context_tokens caused persistent failures.
|
@alt-glitch -- I looked at #35066 and I think these two PRs are complementary rather than competing. Here's my analysis: #35066 fixes #35065 wraps
These target different layers: #35066 removes a guard inside Both could land independently. I've updated the PR description to clarify this scope. Speaking of which — this is also a first-time contributor PR ( |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the former #32604 retry portion. The stale-context_token session fallback is already on current main: send_weixin_direct() delegates to WeixinAdapter.send() (gateway/platforms/weixin.py:2315, 2358-2362), which reaches _send_text_chunk_locked() and retries errcode=-14 without the token (gateway/platforms/weixin.py:1772-1788; commit e105b7ac).
Problems
- The new
"session" in err.lower()check does not itself recognize the current formattederrcode=-14failure form (gateway/platforms/weixin.py:1814-1816). - The proposed
_cache.pop()only removes in-memory state; restored tokens come back from disk after restart unless persistence is updated (gateway/platforms/weixin.py:281-315). - Current main's genuine
-2path opens a rate-limit circuit instead of re-probing (gateway/platforms/weixin.py:1802-1804), so an outer retry needs a conscious reconciliation with that policy.
Suggested changes
- Re-scope any salvage around the current circuit-breaker semantics and add direct-send regression coverage for the chosen behavior.
Automated hermes-sweeper review.
| for _retry in range(2): | ||
| last_result = await _try_send_with_refresh() | ||
| if last_result and last_result.success: | ||
| break |
There was a problem hiding this comment.
This only recognizes an error string containing session, but the existing adapter formats an unhandled -14 response as iLink sendmessage error: ret=... errcode=-14 errmsg=.... Inspect the structured response or explicitly recognize errcode=-14; otherwise the claimed session-error retry can be skipped.
| is_rate = "rate limited" in err or "ret=-2" in err | ||
| is_session = "session" in err.lower() | ||
| if not is_rate and not is_session: | ||
| break |
There was a problem hiding this comment.
This removes only the in-memory cache entry. ContextTokenStore.restore() reloads the account token file after restart, and this path does not call persistence, so the stale token described in the PR will return on the next process start.
What does this PR do?
When
send_weixin_direct()hits rate-limit errors (ret=-2) or session timeout errors (errcode=-14), it now retries once with a 3-second backoff. The stalecontext_tokenis cleared from the token store before retrying, allowing a tokenless fallback send.Previously, these errors caused immediate failure — after a gateway restart, stale
context_tokenscaused persistent delivery failures until manual intervention.Background
This is a partial cherry-pick from the now-superseded PR #32604. The MEDIA regex whitelist changes from that PR were consolidated into #34844 and have already landed. The WeChat retry logic was orthogonal to #34844 and is still unaddressed on
main.Changes Made
gateway/platforms/weixin.py— wrap the send call in a retry loop (up to 2 attempts) that:ret=-2, "rate limited") and session error patternscontext_tokenfrom the token store before retryChecklist
Code
fix(weixin): ...)Documentation