Skip to content

fix(transport): catch all TimeoutError variants in process termination escalation loop - #1155

Open
Echolonius wants to merge 1 commit into
anthropics:mainfrom
Echolonius:fix/subprocess-close-timeout-catch
Open

fix(transport): catch all TimeoutError variants in process termination escalation loop#1155
Echolonius wants to merge 1 commit into
anthropics:mainfrom
Echolonius:fix/subprocess-close-timeout-catch

Conversation

@Echolonius

Copy link
Copy Markdown

🐛 Fix: Catch All TimeoutError Variants in Process Close Escalation Loop

💡 Overview & Root Cause Analysis

In src/claude_agent_sdk/_internal/transport/subprocess_cli.py, the close() method runs inside a shielded cancel scope and uses anyio.fail_after(5) to enforce a graceful shutdown timeout, escalating from wait() to terminate() and finally kill().

However, the escalation loop previously caught only built-in TimeoutError explicitly (except TimeoutError:). Depending on the AnyIO version or backend context (asyncio vs trio), anyio.fail_after can raise anyio.TimeoutError. Catching (TimeoutError, getattr(anyio, "TimeoutError", TimeoutError)) guarantees that the process termination escalation loop (terminate() -> kill()) executes reliably across all Python runtime environments.

🛠️ Solution

Updated the except blocks in SubprocessCLITransport.close() to handle (TimeoutError, getattr(anyio, "TimeoutError", TimeoutError)).

✅ Verification

  • All 146 pytest tests passing cleanly in 2.89s (uv run --with pytest --with pytest-asyncio --with trio pytest tests/test_transport.py).
  • GPG/SSH signed commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant