Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions swe_af/execution/coding_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ async def _call_with_timeout(coro, timeout: int = 2700, label: str = ""):
"""Wrap a coroutine with asyncio.wait_for timeout."""
try:
return await asyncio.wait_for(coro, timeout=timeout)
except asyncio.TimeoutError:
raise TimeoutError(f"Agent call '{label}' timed out after {timeout}s")
except asyncio.TimeoutError as exc:
raise TimeoutError(f"Agent call '{label}' timed out after {timeout}s") from exc


# ---------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions swe_af/execution/dag_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ async def _call_with_timeout(coro, timeout: int = 2700, label: str = ""):
"""
try:
return await asyncio.wait_for(coro, timeout=timeout)
except asyncio.TimeoutError:
except asyncio.TimeoutError as exc:
raise TimeoutError(
f"Agent call '{label}' timed out after {timeout}s"
)
) from exc


# ---------------------------------------------------------------------------
Expand Down
23 changes: 23 additions & 0 deletions tests/test_call_with_timeout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Unit tests for the timeout wrappers used by the execution engine."""

from __future__ import annotations

import asyncio

import pytest

from swe_af.execution.coding_loop import _call_with_timeout as coding_loop_timeout
from swe_af.execution.dag_executor import _call_with_timeout as dag_executor_timeout


@pytest.mark.parametrize("fn", [coding_loop_timeout, dag_executor_timeout])
async def test_call_with_timeout_chains_original_exception(fn):
"""TimeoutError must carry the original asyncio.TimeoutError as its cause."""

async def slow():
raise asyncio.TimeoutError("simulated")

with pytest.raises(TimeoutError) as exc_info:
await fn(slow(), timeout=1, label="test")

assert isinstance(exc_info.value.__cause__, asyncio.TimeoutError)
Loading