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

7.4 KiB
Raw Blame History

id, title, phase, deps, status, created
id title phase deps status created
T-578 ③更新失败时关闭本次新开的商品编辑页(app 建的 tab),只保留成功页由⑤开关决定 7
T-402
T-404b
T-501c
T-571
DONE 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:通过,无输出。