Skip to content

Commit 6a178ae

Browse files
chaxusclaude
andcommitted
docs: report an image-save hang found on production and the verification gap behind it
Saving a document that contains an image inserted by URL blocks the main thread indefinitely (four reproductions, on both the embed path and the main site via ?src=, with localhost-http and same-origin-https images; the same document without an image saves in 3.1s). The UI dialog path could not be automated, so a manual mouse confirmation is still needed before reopening #72. Also records why this was missed: every earlier live check drove the editor through embed-demo's postMessage API, which exercises embed-api rather than the main-site UI and has local saving disabled outright, and only seven of the closed issues have permanent E2E guards while six rest on one-off manual checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 772b40c commit 6a178ae

1 file changed

Lines changed: 94 additions & 0 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# 发现:文档含图片时保存永久卡死(线上复现)+ 验证方法缺口
2+
3+
日期:2026-08-15
4+
线上:https://edit.chaxus.com/ (v9,`a4a58d5` 之后)
5+
起因:用户追问"已关闭的 issue 是否都验证过了,怕问题重新出现",以及
6+
"为什么只验证 embed-demo,常用的是直接在网页上打开编辑"。两个质疑都
7+
成立,顺着查出了一个**真实的、可复现的线上 bug**。
8+
9+
## 一、验证方法的缺口(用户指出,属实)
10+
11+
此前所有线上验证都经 `embed-demo.html` 的 `post()` 接口驱动,原因是它
12+
可编程、能自动化;但代价是**只覆盖了 embed 这条代码路径**
13+
(postMessage → `embed-api.ts`),而主站走的是另一条
14+
(`lib/ui.ts` / `lib/document.ts` / 文件选择 / `saveFileToDisk`)。
15+
尤其保存:embed 模式下本地保存是被**禁用**的
16+
(`routeSavedFile` 里 `isEmbedMode()` 直接 return),所以主站真正的
17+
保存 UX 一次都没被验证过。
18+
19+
**补救方法**:主站的 `?src=` 参数可自动化(也是真实用户流程 + 外部
20+
链接在用)。本轮已用它验证主站:
21+
22+
- ✅ `?src=` 打开远程 docx,渲染正确;
23+
- ✅ 键盘编辑生效(输入 "EDIT" 正常渲染);
24+
- ❌ 含图片保存——见下。
25+
26+
**结论固化**:以后声称"线上已验证"必须区分 embed 路径与主站路径;
27+
embed-demo 通过不等于主站通过。
28+
29+
## 二、已关闭 issue 的验证强度分级(诚实盘点)
30+
31+
| 强度 | issue | 说明 |
32+
| ---------------- | ---------------------------- | ------------------------------ |
33+
| E2E 永久守护 | #113 #31 #28 #13 #33 #25 #87 | CI 每次跑,回归会立刻失败 |
34+
| 线上人工实测一次 | #49 #21 #12 #92 #64 #15 | 无自动化守护,可能静默回归 |
35+
| 仅靠推理 + 单测 | #72 | 本轮复验,**发现问题**(见三) |
36+
| 功能诉求 | #22 #6 | 升级本身即满足 |
37+
38+
即:**只有 7 个有永久守护**,6 个是一次性人工验证。这正是用户担心的
39+
"问题重新出现"的暴露面。
40+
41+
## 三、新发现的 bug:文档含图片时保存永久卡死
42+
43+
**复现步骤**(4 次复现,2 条路径):
44+
45+
1. 打开任意 docx(主站 `?src=` 或 embed `document:open-buffer` 均可);
46+
2. 经 SDK 的 `AddImageUrlAction(url)` 插入一张网络图片——图片能正确
47+
下载并渲染到文档里(截图确认,红色方块可见、带选中控制点);
48+
3. 触发保存(embed 的 `document:save`,或主站的
49+
`asc_DownloadAs(new Asc.asc_CDownloadOptions(65))`);
50+
4. **页面主线程永久阻塞**:CDP 的 `Runtime.evaluate` 全部超时,
51+
截图也超时;最久观察超过 12 分钟仍未恢复,无控制台错误输出。
52+
53+
**对照实验**:同一份 docx **不插图**直接保存 → 3.1 秒完成、产物 25KB
54+
正常 zip。所以卡死与图片直接相关,不是保存链路整体坏了。
55+
56+
**排除的干扰因素**:
57+
58+
- 不是 localhost 图片的问题:换成同源 https 图片
59+
(`https://edit.chaxus.com/img/64.png`)同样卡死;
60+
- 不是 embed 特有:主站 `?src=` 路径同样卡死;
61+
- 不是"慢":12 分钟未完成,且主线程完全阻塞(同步卡死特征)。
62+
63+
**尚未确认(重要,别过度断言)**:
64+
65+
- 插图用的是 SDK 的 `AddImageUrlAction`(我们旧 patch 时代就用它,是
66+
稳定别名)。**UI 路径(Insert → Image → Image from URL 对话框)没能
67+
自动化验证**——对话框输入框对合成 input 事件不认(红色校验感叹号),
68+
属于既有的工具限制,不是产品问题。因此需要**真人用鼠标走一遍 UI**
69+
确认 UI 路径是否同样卡死。
70+
- 本地文件插图(Image from file)未测(文件选择器无法自动化)。
71+
- 粘贴图片(#72 原始报障场景)未测(剪贴板无法自动化)。
72+
73+
**与 #72 的关系**:#72 是"复制进来的图片保存时报错 + 插入在线 url 图片
74+
不显示"。现在"插入 url 图片不显示"这半**已修复**(图片正常渲染),
75+
但"图片 + 保存"这半在新引擎上表现为**卡死**而不是报错。属于同一用户
76+
场景,因此 #72 的关闭需要重新审视(待人工 UI 复核后决定 reopen 还是
77+
另开新 issue)。
78+
79+
**优先级判断**:这是**用户可感知的严重问题**——文档里有图片就存不出来,
80+
且没有任何错误提示,页面直接假死。应排在下一阶段规划所有内容/SEO 项
81+
之前。
82+
83+
## 四、由此产生的行动项
84+
85+
1. **人工 UI 复核**(真人鼠标):Insert → Image from URL / from file →
86+
保存,确认是否复现;若复现则 reopen #72 或另开 issue。
87+
2. **定位根因**:怀疑方向——保存时媒体序列化路径(`writeMediaFiles` /
88+
x2t 媒体合并)在图片存在时进入同步死循环;从编辑器 iframe 内的
89+
`onlyoffice-file-stream` 是否发出可判断卡在编辑器内还是页面侧。
90+
3. **补 E2E 守护**:这个场景必须进回归套件(插图 → 保存 → 校验产物
91+
含 media 条目),否则修好也会再回归。
92+
4. **给一次性人工验证的 issue 补自动化**:#49(.doc 打开)、#21(批注
93+
API)成本低,值得进 E2E;#12/#92/#64(光标与渲染)可用
94+
`cursorPos` + `#ce-cursor` 这类可断言状态覆盖。

0 commit comments

Comments
 (0)