fix(wecom): 最终回复推送失败不再静默(bump 0.52.5)
_bg 最终 push_wecom 的返回值一直被忽略,message/send 失败(如企微 「企业可信 IP」拦截 60020)完全无痕。统一走 _push_checked,失败落 `[wecom] push failed: <reason>` 日志(带企微 errcode/errmsg)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
52db2ef939
commit
5b09ec5c64
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
### 2026-07
|
### 2026-07
|
||||||
|
|
||||||
|
- **07-08 / 0.52.5**:企微最终回复推送失败不再静默——用户报企微连文字也无回复:`_bg` 最终 `push_wecom` 返回值一直被忽略,message/send 失败(如企微「企业可信 IP」拦截 60020)完全无痕。改走 `_push_checked` 统一落 `[wecom] push failed: <reason>` 日志(带企微 errcode/errmsg)。
|
||||||
- **07-08 / 0.52.4**:企微回调加入站留痕日志——用户报企微发语音无反应且 `[wecom-voice]` 日志一行没有(语音分支被调用必打),疑企微侧未投递语音回调;但 text 路径原先零日志无法对照回调通断。解密成功后每条打 `[wecom] inbound msgtype=... from=...`,用"text 行出现、voice 行不出现"即可断定平台侧未投递。个人微信语音已用户实测跑通(0.52.0 链路)。
|
- **07-08 / 0.52.4**:企微回调加入站留痕日志——用户报企微发语音无反应且 `[wecom-voice]` 日志一行没有(语音分支被调用必打),疑企微侧未投递语音回调;但 text 路径原先零日志无法对照回调通断。解密成功后每条打 `[wecom] inbound msgtype=... from=...`,用"text 行出现、voice 行不出现"即可断定平台侧未投递。个人微信语音已用户实测跑通(0.52.0 链路)。
|
||||||
- **07-08 / 0.52.3**:sandbox 镜像 npm 步骤加重试——腾讯 npm 源拉 cytoscape 偶发 ECONNRESET 崩整个 build(部署实测),fetch-retries 2→5 + retry-maxtimeout 120s;RUN 故障兜底补该行,并写明"部署不涉及镜像变化时用 `--skip-build` 跳过重建"。
|
- **07-08 / 0.52.3**:sandbox 镜像 npm 步骤加重试——腾讯 npm 源拉 cytoscape 偶发 ECONNRESET 崩整个 build(部署实测),fetch-retries 2→5 + retry-maxtimeout 120s;RUN 故障兜底补该行,并写明"部署不涉及镜像变化时用 `--skip-build` 跳过重建"。
|
||||||
- **07-08 / 0.52.2**:sandbox 镜像 build 剔除 host-only 依赖——pilk 进 requirements 后镜像 build 也去装它,slim 基底无 gcc 整个 build 编崩(部署实测)。容器内 run_python 用不到语音解码,方案:requirements 行尾标 `# [host-only]`,Dockerfile 装包前 `grep -v '\[host-only\]'` 过滤(通用机制,后续 host-only 依赖复用);不往镜像塞 build-essential(+~250MB 没收益)。
|
- **07-08 / 0.52.2**:sandbox 镜像 build 剔除 host-only 依赖——pilk 进 requirements 后镜像 build 也去装它,slim 基底无 gcc 整个 build 编崩(部署实测)。容器内 run_python 用不到语音解码,方案:requirements 行尾标 `# [host-only]`,Dockerfile 装包前 `grep -v '\[host-only\]'` 过滤(通用机制,后续 host-only 依赖复用);不往镜像塞 build-essential(+~250MB 没收益)。
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||||
# 改版本只动这一行。
|
# 改版本只动这一行。
|
||||||
__version__ = "0.52.4"
|
__version__ = "0.52.5"
|
||||||
|
|
|
||||||
|
|
@ -1666,7 +1666,7 @@ def create_app() -> FastAPI:
|
||||||
"""主动推一条并把失败落日志(push_wecom 不抛错,失败只在返回值里)。"""
|
"""主动推一条并把失败落日志(push_wecom 不抛错,失败只在返回值里)。"""
|
||||||
res = await asyncio.to_thread(_wx.push_wecom, uid, text)
|
res = await asyncio.to_thread(_wx.push_wecom, uid, text)
|
||||||
if not res.ok:
|
if not res.ok:
|
||||||
print(f"[wecom-voice] push failed: {res.reason}")
|
print(f"[wecom] push failed: {res.reason}")
|
||||||
|
|
||||||
async def _bg(uid=uid, content=content, attachments=attachments,
|
async def _bg(uid=uid, content=content, attachments=attachments,
|
||||||
voice_media_id=voice_media_id):
|
voice_media_id=voice_media_id):
|
||||||
|
|
@ -1693,7 +1693,9 @@ def create_app() -> FastAPI:
|
||||||
except Exception as e: # noqa: BLE001
|
except Exception as e: # noqa: BLE001
|
||||||
reply = f"[出错] {type(e).__name__}: {e}"
|
reply = f"[出错] {type(e).__name__}: {e}"
|
||||||
if reply and reply.strip():
|
if reply and reply.strip():
|
||||||
await asyncio.to_thread(_wx.push_wecom, uid, reply)
|
# 最终回复也走 _push_checked:message/send 失败(如企微「企业可信 IP」
|
||||||
|
# 拦截,errcode 60020)原先返回值被忽略纯静默,排查无从下手
|
||||||
|
await _push_checked(uid, reply)
|
||||||
|
|
||||||
# 登记到 inflight:持强引用防 task 被 GC 中途回收 + 关停时 drain(value=None → 不参与
|
# 登记到 inflight:持强引用防 task 被 GC 中途回收 + 关停时 drain(value=None → 不参与
|
||||||
# broker cancel;内层 _run_agent_bg runner 另有自己的 inflight 项负责取消)。
|
# broker cancel;内层 _run_agent_bg runner 另有自己的 inflight 项负责取消)。
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue