回填上传漏拆 data 信封,订单读到了却回填不上 #315

Open
opened 2026-09-18 14:39:52 +08:00 by ila · 1 comment
Owner

原始需求

用户 2026-09-18:「最新agent进入了订单列表第一个订单详情后滑动一次后就失败」。

事实(真机 192.168.0.173:38881,0.9.59,2026-09-18)

回填结果:已检查 1 · 成功 0 · 已回填 0 · 冲突/失败 0,「网络或页面异常,未完整扫描」。

#314 生效:Agent 确实进入了第一个订单的详情页,读到订单编号(实付 51.49 那单),checked 从 0 变成 1。失败在上传这一步。

定位链条:

  1. 「网络或页面异常」是 AgentForegroundService 的兜底文案,只有当异常既不是 IllegalStateException 也不是 IllegalArgumentException 时才出现。
  2. 冲突/失败仍为 0,说明 OrderBackfillUpload 的 confirmed() 一次都没被调用——走的是 else -> throw error,即异常既不是 AgentApiException 也不是 IOException。
  3. 服务端 BackfillOrders 返回 {"data": {"requestId":..., "items":[...]}}(order_backfill_handler.go:24)。
  4. 客户端 backfillOrders 直接把顶层 JSON 交给 parseBackfillResults,第一行 data.getJSONArray("items") 抛 JSONException。

AgentApiClient 里其余每一个接口都写了 .getJSONObject("data"),只有回填这一个漏了。线上接口本身是好的:未带凭据请求返回 401 而非 404。

既有解析用例直接喂内层对象,永远碰不到这层信封,所以单测全绿而真机必失败。

方案

  • backfillOrders 补 .getJSONObject("data")。
  • 新增用例用 ServerSocket 起一个最小 HTTP 服务返回真实信封,走 AgentApiClient.backfillOrders 完整路径。

验收

  • 新增用例通过;去掉 .getJSONObject("data") 后必须变红。
  • 真机回填出现「成功」或「已回填」计数。

未决

详情页那一次滑动尚未解释。act() 在点击失败时会抛「安全页面操作失败」,既然走到了滑动,说明 expansions() 在 Agent 自己的控件树上返回了空。用 uiautomator 的树离线复算:「展开」节点唯一、clickable=true、enabled=true、text=展开、与禁词无几何重叠,判据全部通过。两棵树存在差异,离线无法复现,需要下次运行的证据(下单时间是否回填成功)才能判断展开有没有生效。本工单不处理。

风险与回退

单行改动,回退即去掉该调用。

文档影响

无长期文档影响:接口契约本身未变,只是客户端少拆了一层既有信封。

## 原始需求 用户 2026-09-18:「最新agent进入了订单列表第一个订单详情后滑动一次后就失败」。 ## 事实(真机 192.168.0.173:38881,0.9.59,2026-09-18) 回填结果:**已检查 1 · 成功 0 · 已回填 0 · 冲突/失败 0,「网络或页面异常,未完整扫描」**。 #314 生效:Agent 确实进入了第一个订单的详情页,读到订单编号(实付 51.49 那单),`checked` 从 0 变成 1。失败在**上传**这一步。 定位链条: 1. 「网络或页面异常」是 `AgentForegroundService` 的兜底文案,只有当异常既不是 `IllegalStateException` 也不是 `IllegalArgumentException` 时才出现。 2. 冲突/失败仍为 0,说明 `OrderBackfillUpload` 的 `confirmed()` 一次都没被调用——走的是 `else -> throw error`,即异常既不是 `AgentApiException` 也不是 `IOException`。 3. 服务端 `BackfillOrders` 返回 `{"data": {"requestId":..., "items":[...]}}`(`order_backfill_handler.go:24`)。 4. 客户端 `backfillOrders` 直接把顶层 JSON 交给 `parseBackfillResults`,第一行 `data.getJSONArray("items")` 抛 `JSONException`。 `AgentApiClient` 里其余每一个接口都写了 `.getJSONObject("data")`,只有回填这一个漏了。线上接口本身是好的:未带凭据请求返回 401 而非 404。 既有解析用例直接喂内层对象,永远碰不到这层信封,所以单测全绿而真机必失败。 ## 方案 - `backfillOrders` 补 `.getJSONObject("data")`。 - 新增用例用 `ServerSocket` 起一个最小 HTTP 服务返回真实信封,走 `AgentApiClient.backfillOrders` 完整路径。 ## 验收 - 新增用例通过;去掉 `.getJSONObject("data")` 后必须变红。 - 真机回填出现「成功」或「已回填」计数。 ## 未决 详情页那一次滑动尚未解释。`act()` 在点击失败时会抛「安全页面操作失败」,既然走到了滑动,说明 `expansions()` 在 Agent 自己的控件树上返回了空。用 uiautomator 的树离线复算:「展开」节点唯一、`clickable=true`、`enabled=true`、`text=展开`、与禁词无几何重叠,判据全部通过。两棵树存在差异,离线无法复现,需要下次运行的证据(下单时间是否回填成功)才能判断展开有没有生效。本工单不处理。 ## 风险与回退 单行改动,回退即去掉该调用。 ## 文档影响 无长期文档影响:接口契约本身未变,只是客户端少拆了一层既有信封。
Author
Owner

实施

提交 55017f3(deploy-main)。backfillOrders 补 .getJSONObject("data")。

验证

  • 单测 408 通过 0 失败。
  • 新增 backfill upload parses the server data envelope:用 ServerSocket 起最小 HTTP 服务返回真实 {"data":{...}} 信封,走 AgentApiClient.backfillOrders 完整路径。
  • 反证:去掉 .getJSONObject("data") 后该用例变红。
  • 线上接口存活性:未带凭据 POST 返回 401(非 404),确认服务端已部署。
  • 已装机 192.168.0.173:38881,0.9.59,lastUpdateTime 2026-09-18 14:40:07,无障碍服务仍开启。

未验证

真机回填能否出现「成功/已回填」计数——待人工触发。

未决(不在本工单范围)

详情页那一次滑动:expansions() 在 Agent 自己的控件树上返回空,而用 uiautomator 的树离线复算时该节点各项判据全部通过。需要下次运行的证据判断展开是否生效。

状态:待验收。

## 实施 提交 `55017f3`(deploy-main)。`backfillOrders` 补 `.getJSONObject("data")`。 ## 验证 - 单测 408 通过 0 失败。 - 新增 `backfill upload parses the server data envelope`:用 ServerSocket 起最小 HTTP 服务返回真实 `{"data":{...}}` 信封,走 `AgentApiClient.backfillOrders` 完整路径。 - 反证:去掉 `.getJSONObject("data")` 后该用例变红。 - 线上接口存活性:未带凭据 POST 返回 401(非 404),确认服务端已部署。 - 已装机 192.168.0.173:38881,0.9.59,lastUpdateTime 2026-09-18 14:40:07,无障碍服务仍开启。 ## 未验证 真机回填能否出现「成功/已回填」计数——待人工触发。 ## 未决(不在本工单范围) 详情页那一次滑动:`expansions()` 在 Agent 自己的控件树上返回空,而用 uiautomator 的树离线复算时该节点各项判据全部通过。需要下次运行的证据判断展开是否生效。 状态:待验收。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#315