fix(trading): 每单开跑前先清理购物车,杜绝上一单失败残留被新单一起买走
上一单若在提交(submit_order)之前失败(如 enter_checkout 被 session upgrade 拦截、金额守卫拦下),残留商品会留在购物车里;下一单 add_to_cart 把新商品叠 加在旧商品上,结算时会把上一单的一起买走(已实测踩到过)。 在 execute() 加购前先 clear_cart,从空车起步,保证「一单 = 只买本单商品」—— 不依赖上一次失败路径是否完整执行清理,进程中途崩溃残留也没人清也能兜住。 清理后 cart_count 仍未清空(含 count API 失败返回 -1)按闸门语义转 needs_human, 绝不带残留往下加购。清理本身是本机侧卫生操作,不走证据与上报。 补 3 个用例:clear 先于 add、清理后非空/未知 → 转 needs_human 且不加购; 并为走 execute 的既有测试补 clear_cart 桩。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -256,11 +256,12 @@ class WorkerRunner:
|
||||
)
|
||||
|
||||
async def execute(self, task: LeaseTask) -> None:
|
||||
"""站点交互的实际调度:加购 → 校验 → 确认页 → 金额守卫 → 提交 → 付款
|
||||
"""站点交互的实际调度:清购物车 → 加购 → 校验 → 确认页 → 金额守卫 → 提交 → 付款
|
||||
|
||||
每一步的顺序:动作 → 落证据 → 写本地 SQLite → 回报 gateway。
|
||||
站点交互当前未实现(site_interact 抛 NotImplementedError),第一步就会
|
||||
转到 _execute_with_renewal 的 except 分支上报 needs_human。
|
||||
开单前的「清购物车」是本机侧卫生步骤(step 0,见下方代码注释),不走
|
||||
证据与上报;站点交互失败会转 _execute_with_renewal 的 except 分支上报
|
||||
needs_human / failed。
|
||||
"""
|
||||
await self._db.ensure_started(task.task_id, task.site, task.intent)
|
||||
|
||||
@@ -268,6 +269,26 @@ class WorkerRunner:
|
||||
if task.site != "rakuten":
|
||||
raise NotImplementedError(f"site={task.site} 暂不在交易服务范围内(仅 rakuten)")
|
||||
|
||||
# 步骤 0:开单前清理购物车。上一单若在提交(submit_order)之前失败——比如
|
||||
# 加购成功但 enter_checkout 被 session upgrade 拦截、或金额守卫拦下——残留的
|
||||
# 商品不会自己消失,会一直留在购物车里;下一次 add_to_cart 把新商品叠加在旧
|
||||
# 商品上,结算时会把上一单的一起买走(已实测踩到过)。所以每单开跑前先清空
|
||||
# 购物车,保证「一单 = 只买本单商品」的不变式——无论上一单是怎么失败的
|
||||
# (包括进程中途崩溃,残留都没人清),这里都从空车起步。
|
||||
#
|
||||
# 这条不在 gateway 上报,也不写步骤证据:它是本机侧的卫生操作,不是订单
|
||||
# 进度的状态迁移。清理后 count 非 0(含 count API 拿不到结果返回 -1)说明
|
||||
# 清理没跑干净,**不能**带着残留往下加购——有把上一单买走的真实风险,
|
||||
# 按闸门语义拦截转 needs_human,宁可卡住等人核对,也不赌「残留不会被买走」。
|
||||
cleared = await self._site.clear_cart()
|
||||
if cleared.get("cart_count", -1) != 0:
|
||||
raise OrderGuardError(
|
||||
"开单前清理购物车后仍未清空"
|
||||
f"(cart_count={cleared.get('cart_count')},removed_count="
|
||||
f"{cleared.get('removed_count')}):残留商品可能随本次下单一起被买走,"
|
||||
"中止转人工核对"
|
||||
)
|
||||
|
||||
# 步骤 1:加购
|
||||
await self._run_step(
|
||||
task, step_no=1, step_name="cart-add",
|
||||
|
||||
Reference in New Issue
Block a user