Fix reconnection wait timeout to cover full auto-reconnect window

The circuit breaker and agent error handler were using a hardcoded 20s
timeout, but the worst-case auto-reconnect window is ~48s (3 attempts *
15s + 7s delays). Handlers would raise ConnectionError while reconnection
was still in progress. Now both use BrowserSession.RECONNECT_WAIT_TIMEOUT
(54s) derived from the actual reconnect parameters.
This commit is contained in:
Saurav Panda
2026-02-23 17:47:52 -08:00
parent 032f1475cb
commit 719d0361e5
3 changed files with 13 additions and 5 deletions

View File

@@ -1226,9 +1226,12 @@ class Agent(Generic[Context, AgentStructuredOutput]):
if self._is_connection_like_error(error):
# If reconnection is in progress, wait for it instead of stopping
if self.browser_session.is_reconnecting:
self.logger.warning(f'🔄 Connection error during reconnection, waiting for reconnect: {error}')
wait_timeout = self.browser_session.RECONNECT_WAIT_TIMEOUT
self.logger.warning(
f'🔄 Connection error during reconnection, waiting up to {wait_timeout}s for reconnect: {error}'
)
try:
await asyncio.wait_for(self.browser_session._reconnect_event.wait(), timeout=20.0)
await asyncio.wait_for(self.browser_session._reconnect_event.wait(), timeout=wait_timeout)
except TimeoutError:
pass

View File

@@ -517,6 +517,9 @@ class BrowserSession(BaseModel):
_demo_mode: 'DemoMode | None' = PrivateAttr(default=None)
# WebSocket reconnection state
# Max wait = attempts * timeout_per_attempt + sum(delays) + small buffer
# Default: 3 * 15s + (1+2+4)s + 2s = 54s
RECONNECT_WAIT_TIMEOUT: float = 54.0
_reconnecting: bool = PrivateAttr(default=False)
_reconnect_event: asyncio.Event = PrivateAttr(default_factory=asyncio.Event)
_reconnect_lock: asyncio.Lock = PrivateAttr(default_factory=asyncio.Lock)

View File

@@ -98,14 +98,16 @@ class BaseWatchdog(BaseModel):
if event.event_type not in LIFECYCLE_EVENT_NAMES and not browser_session.is_cdp_connected:
# If reconnection is in progress, wait for it instead of silently skipping
if browser_session.is_reconnecting:
wait_timeout = browser_session.RECONNECT_WAIT_TIMEOUT
browser_session.logger.debug(
f'🚌 [{watchdog_class_name}.{actual_handler.__name__}] ⏳ Waiting for reconnection...'
f'🚌 [{watchdog_class_name}.{actual_handler.__name__}] ⏳ Waiting for reconnection ({wait_timeout}s)...'
)
try:
await asyncio.wait_for(browser_session._reconnect_event.wait(), timeout=20.0)
await asyncio.wait_for(browser_session._reconnect_event.wait(), timeout=wait_timeout)
except TimeoutError:
raise ConnectionError(
f'[{watchdog_class_name}.{actual_handler.__name__}] Reconnection wait timed out after 20s'
f'[{watchdog_class_name}.{actual_handler.__name__}] '
f'Reconnection wait timed out after {wait_timeout}s'
)
# After wait: check if reconnection actually succeeded
if not browser_session.is_cdp_connected: