fix: catch asyncio.CancelledError in close_mcp shutdown
When an MCP server (e.g. stdio browser-agent subprocess) does not
terminate within the AsyncExitStack.aclose() timeout, asyncio raises
CancelledError. The existing exception handler only caught RuntimeError
and BaseExceptionGroup, so CancelledError escaped the except block and
crashed nanobot with exit code 1 on every shutdown.
Add asyncio.CancelledError to the caught exception tuple so the error
is logged at debug level and shutdown completes cleanly.
Stack trace from the crash:
Traceback (most recent call last):
File ".../nanobot/agent/loop.py", line 1194, in close_mcp
await stack.aclose()
asyncio.exceptions.CancelledError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".../asyncio/__main__.py", line ?, in <module>
File ".../nanobot/agent/loop.py", line ?, in close_mcp
...
RuntimeError: ... (or BaseExceptionGroup) not caught
SystemExit: 1
This commit is contained in:
@@ -1410,6 +1410,10 @@ async def _close_server(state: Any, server_name: str) -> None:
|
||||
return
|
||||
try:
|
||||
await stack.aclose()
|
||||
except asyncio.CancelledError:
|
||||
if asyncio.current_task().cancelling() > 0:
|
||||
raise
|
||||
logger.debug("MCP server '{}' cleanup error (can be ignored)", server_name)
|
||||
except (RuntimeError, BaseExceptionGroup):
|
||||
logger.debug("MCP server '{}' cleanup error (can be ignored)", server_name)
|
||||
|
||||
@@ -1423,5 +1427,9 @@ async def close_mcp_servers(state: Any) -> None:
|
||||
for name, connection in connections:
|
||||
try:
|
||||
await connection.aclose()
|
||||
except asyncio.CancelledError:
|
||||
if asyncio.current_task().cancelling() > 0:
|
||||
raise
|
||||
logger.debug("MCP server '{}' cleanup error (can be ignored)", name)
|
||||
except (RuntimeError, BaseExceptionGroup):
|
||||
logger.debug("MCP server '{}' cleanup error (can be ignored)", name)
|
||||
|
||||
Reference in New Issue
Block a user