Classify heartbeat lease failures

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b6f-7db1-7222-918b-e813a6bda38d
This commit is contained in:
tegwick 2026-08-23 14:42:30 +02:00
parent ad4074c20a
commit 84b4089f8a
6 changed files with 84 additions and 14 deletions

View file

@ -33,7 +33,22 @@ DEFAULT_REPO_ROOTS = ("~", "~/work")
class OpsRunError(RuntimeError):
pass
"""Bounded Activity Core failure with optional HTTP classification."""
def __init__(
self,
message: str,
*,
action: str | None = None,
status_code: int | None = None,
) -> None:
super().__init__(message)
self.action = action
self.status_code = status_code
@property
def lease_rejected(self) -> bool:
return self.status_code in {401, 403, 404, 409, 410, 412, 423}
@dataclass
@ -159,8 +174,14 @@ class ActivityCoreOpsClient:
timeout=self.config.timeout,
)
resp.raise_for_status()
except httpx.HTTPStatusError as exc:
raise OpsRunError(
f"list ops-runs failed: HTTP {exc.response.status_code}",
action="list",
status_code=exc.response.status_code,
) from exc
except httpx.HTTPError as exc:
raise OpsRunError(f"list ops-runs failed: {exc}") from exc
raise OpsRunError("list ops-runs failed: transport error", action="list") from exc
data = resp.json()
items = data.get("items") if isinstance(data, dict) else data
if not isinstance(items, list):
@ -190,8 +211,14 @@ class ActivityCoreOpsClient:
timeout=self.config.timeout,
)
resp.raise_for_status()
except httpx.HTTPStatusError as exc:
raise OpsRunError(
f"claim failed: HTTP {exc.response.status_code}",
action="claim",
status_code=exc.response.status_code,
) from exc
except httpx.HTTPError as exc:
raise OpsRunError(f"claim failed: {exc}") from exc
raise OpsRunError("claim failed: transport error", action="claim") from exc
data = resp.json()
items = data.get("items") if isinstance(data, dict) else []
return [OpsRun.from_api(item) for item in items if isinstance(item, dict)]
@ -247,8 +274,16 @@ class ActivityCoreOpsClient:
timeout=self.config.timeout,
)
resp.raise_for_status()
except httpx.HTTPStatusError as exc:
raise OpsRunError(
f"{action} ops_run {run_id} failed: HTTP {exc.response.status_code}",
action=action,
status_code=exc.response.status_code,
) from exc
except httpx.HTTPError as exc:
raise OpsRunError(f"{action} ops_run {run_id} failed: {exc}") from exc
raise OpsRunError(
f"{action} ops_run {run_id} failed: transport error", action=action
) from exc
return OpsRun.from_api(resp.json())