Files
cmshoppe/docs/tasks/T-578.md
T

91 lines
7.4 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, T-404b, T-501c, T-571]
status: DONE
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 原样留着。这是「失败保全现场」的原设计。
用户决定:**失败时关闭本次由程序自动新建的商品编辑页**,理由——失败原因/上传状态已进 run_logs 与诊断日志(`_notify_apply_step` 失败详情、run 事件),关掉页面不丢诊断数据;而失败页上的改动(删了旧封面、传了新图但未排首位)都是**未提交**表单状态,关闭 = Shopee 编辑器丢弃这些草稿,**线上商品不受影响**(未点「更新」即未持久化),重试会重新开页从头跑 `replace_cover`。累积的失败 tab(重试还会复用、进而连成功后也关不掉)问题一并消除。
保留的边界:**只关 `created_by_app=True` 的 tab**;若复用用户已经打开的商品编辑页,只断开 CDP 连接,不关闭浏览器 tab。
## 方案(改哪个文件、改成什么)
### `app/editor.py` — `apply_task` finally + `_close_applied_product`
统一口径:**app 新开的 tab 在「失败」或「成功且⑤开关开」时关闭;复用的 tab 永不关。** 成功页默认保留(供人工复核,⑤开关控制),失败页直接关。
- 改 `finally` 的传参与 `_close_applied_product`,不要继续把 `close_success_tab and committed` 预先折叠成布尔值,避免失败状态在调用处丢失。建议签名与调用改为:
- `finally: _close_applied_product(cdp, committed=committed, close_success_tab=close_success_tab)`
- `def _close_applied_product(cdp, committed=False, close_success_tab=False): ...`
- `_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)` 只用于成功且 `close_success_tab=True` 的路径**(让「更新成功」状态渲染后再关,是人工复核缓冲);失败关闭不需要该延时,避免每条失败多等 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 新开页(复用页不关)、成功页由⑤开关决定」。
- `docs/api.md` 里 `apply_task()` / ③更新流程关于“失败任务保留现场”的接口说明同步改为同一口径,避免 API 文档与实现冲突。
## 验收要点
- `replace_cover` 返回 `ok=False`(如 `DRAG_NOT_FIRST`/`UPLOAD_TIMEOUT`)且 `created_by_app=True` → `apply_task` 结束后 `close_tab` 被调用,且不调用 `time.sleep(2)`。
- `replace_cover` 返回 `ok=False` 且 `created_by_app=False` → 只 `cdp.close()` 断开连接,不调用 `close_tab`。
- `change_title` 失败、`click_update` 未点成、`apply_task` 抛异常各分支:`created_by_app=True` 时关闭 app 新开 tab,`created_by_app=False` 时不关闭浏览器 tab。
- 成功且 `close_success_tab=False`(默认)→ tab **保留**,不调用 `time.sleep(2)`(既有行为不回归)。
- 成功且 `close_success_tab=True` → 先 `time.sleep(2)`,再关闭 app 新开 tab。
- 复用的既有 tab(`created_by_app=False`)→ 失败/成功均不调用 `close_tab`。
- `open_product()` 内部打开/就绪失败仍由 `_close_open_product_failure` 负责清理本轮自动新建 tab;本任务不重复改这条早期失败路径。
- 失败原因/上传状态仍出现在 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。
- 不改「失败不写回蝦皮」的既有安全事实(失败页本就未提交)。
## 执行记录
- 2026-07-09:已完成。
- 文档预提交:
- 先按评审建议更新任务定义并单独提交 `7c606e8 T-578 更新任务定义`:补依赖、明确只关闭程序自动新建页、实现时传完整 `committed`、同步 `docs/api.md`、细化验收分支。
- 代码:
- `app/editor.py`:`apply_task()` finally 改为 `_close_applied_product(cdp, committed=committed, close_success_tab=close_success_tab)`;`_close_applied_product()` 内部统一判断 tab 生命周期。
- 更新失败(`committed=False`,含标题失败、封面失败、更新按钮/确认失败、异常分支)且 `created_by_app=True` 时关闭浏览器 target;复用用户已有 tab 时只断开 CDP。
- 成功路径保持原语义:`close_success_tab=False` 时保留;`close_success_tab=True` 且 app 新建页时先等 2 秒再关闭。失败关闭不等待 2 秒。
- `tests/test_editor_login.py`:补/改成功默认保留、失败关闭、复用失败不关、封面失败关闭、异常关闭等单测。
- 文档:
- `docs/04-architecture.md`:更新 `close_success_tab`、③真实更新、CDP tab 生命周期表述。
- `docs/api.md`:同步 `apply_task()` 和 ③更新流程接口说明,移除“失败保留现场”的旧口径。
- 验证:
- `py -3.10 -m unittest tests.test_editor_login`:通过,45 tests。
- `py -3.10 -m unittest tests.test_editor_login tests.test_gui`:通过,184 tests。
- `python -m ruff check app tests main.py`:通过。
- `py -3.10 -m compileall app main.py`:通过。
- `py -3.10 -m unittest discover -s tests`:通过,316 tests。
- `git diff --check`:通过,无输出。