5.2 KiB
5.2 KiB
id, title, phase, deps, status, created
| id | title | phase | deps | status | created | ||
|---|---|---|---|---|---|---|---|
| T-552 | 任务失败原因带上失败步骤(①②③ 阶段/状态列可见) | 7 |
|
DONE | 2026-07-08 |
问题 / 背景
①导入采集(及②③)列表里任务失败时,阶段/状态列只显示「失败」,操作员看不出卡在哪一步(打开商品页 / 页面就绪 / 读标题 / 读封面 / 下载封面 / 写库 / 回写Excel)。
- 失败步骤信息其实已被采集:T-207 把
step=preflight/open_product/wait_ready/read_title/read_cover/download_cover/db_write/excel_write_back记进了run_log_events。 - 但
db.mark_failed(task_id, phase, error)里phase只是粗粒度(collect/generate/apply),error只是原始消息;tasks.last_error不含步骤。 - ① 阶段列的 tooltip 已经在显示
last_error,但只有消息、没有步骤 → 要知道哪步得去翻「采集运行日志」逐条对,摩擦大。
这是"数据有、但没暴露在失败发生处"的可见性问题,不是要重新采集数据。
方案(P0:prepend 步骤到 last_error,最小改动)
让失败的 last_error 带上中文步骤,例如「读封面失败:图片超过大小上限」「打开商品页失败:CDP 端口无响应」。
- worker(
app/gui/workers.py的CollectWorker,及②③对应 worker):失败时 worker 已知当前 step(T-207 在逐任务追踪),把该 step 传给失败写库。 - db(
app/db.pymark_failed):把中文步骤 prepend 到last_error(不改 schema),存成「<步骤中文>失败:<原因>」;step 已是中文/已知失败步骤时避免重复前缀。 - step→中文映射(放一处共用,如 worker 或 db helper):
preflight→预检 / open_product→打开商品页 / wait_ready→页面就绪 / read_title→读标题 / read_cover→读封面 / download_cover→下载封面 / db_write→写库 / excel_write_back→回写Excel;未知 step 用原值兜底。 - 展示:①②③ 的阶段/状态列 tooltip 已显示
last_error(含步骤后即自动可见);阶段列文案可选显示「失败·<步骤>」(能从 last_error 派生就派生,不额外加列)。 - 三个模块共用同一套 step→中文 + prepend 逻辑,一次覆盖①②③"失败看不出哪步"。
备注:更结构化的做法是新增
tasks.last_error_step字段(便于阶段列内联显示/上色),但需 schema 迁移;本任务按 P0 走 prepend,last_error_step作为后续可选增强,双击看完整步骤链(run_log_events 按 task_id 过滤)也作为后续 P1。
验收要点
- 采集/生成/更新任一步失败后,
tasks.last_error以「<中文步骤>失败:<原因>」开头。 - ①②③ 失败行悬停 tooltip 能看到"是哪一步失败 + 原因",无需翻运行日志。
- step→中文映射覆盖上述所有步骤,未知 step 不崩、用原值。
- 已带步骤前缀的 error 不重复加前缀。
- 单测:
tests/test_db.py断言mark_failed带 step 时last_error前缀正确、无 step 时保持原样;tests/test_gui.py断言失败行 tooltip 含步骤文案(至少①覆盖,②③视改动补充)。
边界(不改什么)
只改 mark_failed 的 step 前缀 + worker 传 step + 模型 tooltip/阶段文案 + 单测;不改采集/生成/更新执行流程、run_log_events 结构(T-207 保留)、CDP/Shopee 交互、Excel、DB schema(P0 不加字段)。
执行记录
- 2026-07-08:完成 T-552。
- 代码:
app/db.py新增FAILURE_STEP_LABELS、failure_step_label()、format_failure_error();mark_failed()与set_applied()增加可选step参数,带 step 时把last_error统一保存为「<中文步骤>失败:<原因>」,无 step 时保持旧行为,已带步骤前缀时不重复添加。 - 代码:①
CollectWorker采集失败时把当前 step 传给mark_failed,并立即向 GUI 发出带步骤前缀的last_error;②app/ai.py的生成失败写库传入当前 title/cover step;③ApplyWorker更新失败和异常失败传入当前 step 给set_applied,默认归因为apply_task,真实编辑器步骤仍由on_step覆盖。 - 展示:①②③ 表格模型原本 tooltip 已读取
last_error,因此失败行悬停可直接看到失败步骤与原因;未新增列、不改 DB schema、不改 run_log_events。 - 测试:
tests/test_db.py覆盖mark_failed带 step 前缀、未知 step 兜底、重复前缀不叠加、无 step 保持原样,以及set_applied更新失败 step 前缀;tests/test_gui.py覆盖①②③失败行 tooltip 显示步骤与原因,并更新③ worker 失败原因断言。 - 验证:
py -3.10 -m unittest discover -s tests -p "test_db.py"通过(9 tests);py -3.10 -m unittest discover -s tests -p "test_gui.py"通过(104 tests);py -3.10 -m unittest discover -s tests -p "test_ai.py"通过(40 tests);python -m ruff check app tests main.py通过;python -m ruff check scripts\gen_task_board.py tests\test_task_board.py通过;py -3.10 -m compileall app main.py通过;py -3.10 -m py_compile scripts/gen_task_board.py通过;git diff --check通过;py -3.10 -m unittest discover -s tests通过(257 tests)。