Skip to content

[Feishu][Health] WS 鉴权失败仍输出 bridge online,worker 被误判为健康 #452

Description

@vansin

问题

Feishu worker 当前把 WSClient.start() 的 Promise resolve 当成“长连接已鉴权并 ready”。但 SDK 的真正连接生命周期由 onReady / onError 等回调表达;当前实现未接这些信号,start() 返回后就无条件写 connected: true,随后 worker 输出 bridge online

已保存的 dummy-credential smoke 证明:同一份 stderr 可以同时出现 failed to obtain token[feishu:worker] bridge online,worker 仍长期存活。因此文档和运维会把一个本地启动标记误判成飞书鉴权 / WebSocket 成功。

Related: #261(其 liveness 范围更广;本 issue 聚焦启动成功契约与鉴权失败健康状态)。

代码与实测证据

安全复现(不发消息)

优先用 Mock WSClient:

  1. start() resolve,但触发 onError(new Error('auth failed')),不触发 onReady
  2. 当前行为:adapter connected=true、worker 输出 bridge online、进程继续存活。
  3. 另可用纯假 App ID / Secret 做隔离连接层 smoke,复现报告中的 failed to obtain token + bridge online;到鉴权 / 连接层即止,绝不发送消息。

期望修复 / 验收标准

  • startFeishuBridge() 只有在 SDK onReady(真实 WS handshake ready)后才 resolve / 宣告成功;WSClient.start() resolve 本身不构成成功。
  • 全进程只有一条权威成功行,例如现有 [feishu:worker] bridge online ...,且只从首次 onReady 路径输出一次;鉴权失败、connecting、reconnecting 时不得出现。
  • 首次连接 onError / 鉴权失败:adapter health 保持 connected=false 并记录 scrub 后的 lastError;worker 输出明确失败行并非零退出,让父 supervisor 将其视为不健康。
  • 已 ready 后进入 reconnect 时标记非健康 / 非 connected;onReconnected 后恢复;terminal onError 不能留下长期存活的绿色 worker。
  • 启动等待有有界超时,避免 DNS / proxy 卡死时永久假健康;任何日志都不得包含 App Secret。
  • 单元测试覆盖:start resolve 但未 onReady、onReady、onError before ready、onError after ready、reconnect / reconnected、成功行 exactly once、secret scrub。
  • Docker 分层 smoke 只验连接 / 鉴权层并保存报告;无测试 App 时真实 ready 用例必须明确 SKIP / 🚫,不能拿 dummy 凭据进程存活代替 PASS。

安全边界

不得向任何 live 飞书群 / 真实用户发消息;不得触碰生产 Feishu 节点、配置或 PID。默认使用 mock;若后续提供纯测试企业 App,也只验到 onReady 后立即停止,不触发消息事件。

文档已在 98f3b7ee 明确标注 bridge online 当前不是连接成功证据。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions