makecindy / makecindy/cindy

IM: rejectAllPending 清空交互时不收口卡片,dispose 后留下死按钮

Open
#1,731 1 comment 0 reactions 1 assignee Claimed by @zqchris View on GitHub
Dominant language
TypeScript
Stars
2.7k
Forks
395
Avg merge
21h 48m
Merged PRs (30d)
776

Description

## 问题

`disposeAllSessions` 走 `rejectAllPending('session disposed')` 把所有等待中的交互一次性清掉,但**一张卡片都不动**。用户会留下一堆看着能点、实际已经没人认的按钮。

代码位置:

- `apps/desktop/src/main/im/shared/turnRunner.ts:2814` —— `rejectAllPending('session disposed')`
- `apps/desktop/src/main/im/shared/pendingInteractions.ts` —— `rejectAllPending` 遍历 `pending` 逐个 `entry.reject(...)` 后 `pending.clear()`,`entry.messageId` 全程没被用到

触发场景:IM 换账号、下线、退出等需要 dispose 全部 session 的时刻。

## 与 #1711 的关系

#1711 修的是 `cancelPending` 那条路径(turn 收口 / session 清理 / 抢跑 / 超时),做法是让它把 `entry.messageId` 交还给调用方,由 `turnRunner` 的 `dropInteractionCard` 把卡片收口成失效态。

`rejectAllPending` 是**同一个病的另一处**,而且更糙:`cancelPending` 至少还按"拒绝"语义好好 resolve 了一次,这条直接 `reject` 抛错。#1711 有意没动它,避免把范围扩大。

## 修法

与 #1711 同构,改动应该很小:

1. `rejectAllPending` 交还被清掉的那批 `messageId`(例如返回 `string[]`),仍然不做 IO
2. `turnRunner` 在 dispose 路径上拿到这批地址,逐个把卡片收口成失效态(复用 `dropInteractionCard` 里已有的 `adapter.interactionExpiredNotice` + `cards.buildResolvedCard` 那段)

需要注意的边界:dispose 期间 IM 连接可能正在关闭,卡片编辑大概率会失败。收口动作必须是尽力而为(失败只记 warn),不能拖慢或阻断 dispose 本身。

## 影响

修好之前:换账号 / 下线 / 退出时,所有正在等待确认的卡片都会变成死卡 —— 按钮还在,点了没有任何反应,用户不知道它已经失效。

## 验收标准

1. dispose 全部 session 时,所有等待中的交互卡被收口成失效态(正文改写 + 按钮消失)
2. 收口失败不阻断 dispose,只记 warn
3. 未配置 `interactionExpiredNotice` 的渠道行为不变(与 #1711 保持一致的可选能力位语义)
4. 带回归测试

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.