Files
cmshoppe/docs/tasks/T-578.md
T
chengmaandClaude Opus 4.8 81b5788436 docs(tasks): add T-578 close app-created edit tab on apply failure
③更新失败(拖拽/上传失败、抛异常等 committed=False)时直接关闭本次
程序新开的商品编辑页(created_by_app 守卫,复用页不关);成功页仍由
⑤开关决定。失败诊断已进 run_logs、失败页为未提交草稿关闭不影响线上。
失败关闭去掉成功路径的 2s 渲染缓冲。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 20:36:53 +08:00

68 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-578
title: ③更新失败时关闭本次新开的商品编辑页(app 建的 tab),只保留成功页由⑤开关决定
phase: 7
deps: [T-402]
status: TODO
created: 2026-07-09
---
## 问题 / 背景
③更新蝦皮时,`apply_task`(`app/editor.py:1414`)在对应账号 Chrome 里为商品新开编辑页;当拖图到第一位失败(`DRAG_NOT_FIRST`)、上传超时等**失败**时,页面不会自动关闭。
根因(已核):`finally` 里 `_close_applied_product(cdp, close_success_tab=close_success_tab and committed)`(`editor.py:1512`)。关闭 tab 需同时满足 `close_success_tab`(⑤设置「成功后关闭本次新开编辑页」,默认 False)**且** `committed`(点了「更新」才为 True)。失败时 `committed=False`,条件必然不成立 → `cdp.close()` 只断 WebSocket、tab 原样留着。这是「失败保全现场」的原设计。
用户决定:**失败也直接关闭本次由程序新开的 tab**,理由——失败原因/上传状态已进 run_logs 与诊断日志(`_notify_apply_step` 失败详情、run 事件),关掉页面不丢诊断数据;而失败页上的改动(删了旧封面、传了新图但未排首位)都是**未提交**表单状态,关闭 = Shopee 编辑器丢弃这些草稿,**线上商品不受影响**(未点「更新」即未持久化),重试会重新开页从头跑 `replace_cover`。累积的失败 tab(重试还会复用、进而连成功后也关不掉)问题一并消除。
保留的边界(按分析建议):**只关 `created_by_app=True` 的 tab**,绝不关用户自己已打开、程序复用的页面。
## 方案(改哪个文件、改成什么)
### `app/editor.py` — `apply_task` finally + `_close_applied_product`
统一口径:**app 新开的 tab 在「失败」或「成功且⑤开关开」时关闭;复用的 tab 永不关。** 成功页默认保留(供人工复核,⑤开关控制),失败页直接关。
- 改 `finally` 的传参与 `_close_applied_product`,使关闭判定为:
- `created_by_app and target_id and ((not committed) or close_success_tab)`。
- 即:`committed=False`(含 `replace_cover` 失败、`change_title` 失败、`click_update` 未点成、抛异常各分支)→ 关;`committed=True` 且 `close_success_tab` → 关;`committed=True` 且开关关 → 保留(不变)。
- **关闭前的 `time.sleep(2)` 只用于成功路径**(让「更新成功」状态渲染后再关,是人工复核缓冲);失败关闭不需要该延时,避免每条失败多等 2 秒拖慢批量。
- 复用现有 `close_tab`(`app/cdp.py`),关闭异常继续 try/except 吞掉(沿用现状,关不掉不致命)。
- 早期打开就失败仍走 `_close_open_product_failure`(`editor.py:745`,本就关 app tab),与本改动口径一致,不动。
### 影响面确认(不新增 worker/配置)
- 调用方 `ApplyWorker`(`workers.py:939`)传参不变(`close_success_tab` 仍来自⑤设置,只影响成功路径);**不新增设置项**——失败关闭是无条件行为(受 `created_by_app` 守卫),符合「失败了直接关闭」。
- ⑤「成功后关闭本次新开编辑页」文案/语义不变(它本就只管成功页)。
### 文档同步
- `docs/04-architecture.md` 第七节 CDP 已验证事实里「③更新失败保留页面」的表述,更新为「③更新失败关闭 app 新开页(复用页不关)、成功页由⑤开关决定」。
## 验收要点
- `replace_cover` 返回 `ok=False`(如 `DRAG_NOT_FIRST`/`UPLOAD_TIMEOUT`)→ `apply_task` 结束后 `close_tab` 被调用(单测 mock:`created_by_app=True` 时关闭、`created_by_app=False` 时不关)。
- `change_title` 失败、`click_update` 未点成、`apply_task` 抛异常各分支 → 同样关闭 app 新开 tab。
- 成功且 `close_success_tab=False`(默认)→ tab **保留**(既有行为不回归)。
- 成功且 `close_success_tab=True` → tab 关闭、保留 2 秒渲染缓冲。
- 复用的既有 tab(`created_by_app=False`)→ 失败/成功均不关。
- 失败原因/上传状态仍出现在 run_logs / 诊断日志(关闭不吞诊断)。
- 验证命令(unittest,不引入 pytest):
- `py -3.10 -m unittest tests.test_editor_login tests.test_gui`
- `python -m ruff check app tests main.py`
- `py -3.10 -m compileall app main.py`
- `py -3.10 -m unittest discover -s tests`
- `git diff --check`
## 边界(不改什么)
- 不关闭复用的用户自有页面(`created_by_app=False`)。
- 不改 ①采集关闭逻辑(`_close_collected_product`)、④登录页。
- 不新增⑤设置项;不改 `close_success_tab` 对成功路径的语义。
- 不改 `replace_cover`/`change_title`/`click_update` 交互本身、CDP 选择器、DB、AI/cmhub。
- 不改「失败不写回蝦皮」的既有安全事实(失败页本就未提交)。
## 执行记录
(做完在这里写:改了什么文件、跑了什么验证命令及结果、遇到的阻塞、关键决策。)