fix(soak): 环境客户端把传输层失败也翻成 AppWorldError,「连不上」那一档原本没实现
execute 的 docstring 一直写着「只有环境自己坏了——连不上、HTTP 非 2xx、返回体不是约定 形状——才抛 AppWorldError」,但实现里只处理了后两档。连不上、读超时、连接中途断掉时, httpx 抛的是它自己的异常类型,而上层的动作执行接缝只认 AppWorldError,于是容器一挂整次 运行会以一个未捕获的第三方异常炸出去,正确的行为是记成环境故障、由库合成一段观察、以 env_error 收尾。 这个缺口是压测里真把容器 docker kill 掉之后才暴露的——在那之前它只写在 docstring 里。 顺带覆盖了另一个一直没验过的路径:客户端读超时同属这一类。 CancelledError 继承 BaseException,不在 httpx.HTTPError 的范围内,取消照旧原样穿过去。 修完重跑那一类,七条判据仍然全过。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+15
-2
@@ -796,8 +796,21 @@ async def _post_json(
|
||||
path: str,
|
||||
body: Mapping[str, Any],
|
||||
) -> Any:
|
||||
"""打一个 POST,检查状态码,剥掉 environment server 统一的 output 包装。"""
|
||||
response = await client.post(f"{base_url}{path}", json=dict(body))
|
||||
"""打一个 POST,检查状态码,剥掉 environment server 统一的 output 包装。
|
||||
|
||||
**传输层的失败也要翻成 `AppWorldError`。** 连不上、读超时、连接中途断掉,httpx 抛的是
|
||||
它自己的异常类型,而上层的动作执行接缝只认 `AppWorldError`——不翻的话,容器挂掉会让整
|
||||
次运行以一个未捕获的第三方异常炸出去,而正确的行为是记成环境故障、由库合成一段观察、
|
||||
以 `env_error` 收尾。这个缺口是压测里真把容器 `docker kill` 掉之后才暴露的:在那之前
|
||||
「连不上」这一档只写在上面那个 docstring 里,没有实现。
|
||||
|
||||
`asyncio.CancelledError` 不在 `httpx.HTTPError` 的范围内(它继承 `BaseException`),
|
||||
所以取消照旧原样穿过去。
|
||||
"""
|
||||
try:
|
||||
response = await client.post(f"{base_url}{path}", json=dict(body))
|
||||
except httpx.HTTPError as exc:
|
||||
raise AppWorldError(f"{path} 的请求没能完成:{type(exc).__name__}: {exc}") from exc
|
||||
if response.is_error:
|
||||
raise AppWorldError(f"{path} 返回 HTTP {response.status_code}:{response.text[:2000]}")
|
||||
payload = response.json()
|
||||
|
||||
Reference in New Issue
Block a user