fix(tools): wrap browser provider network calls with error handling

Wrap requests.post() in create_session() for browser_use, browserbase,
and firecrawl providers with requests.RequestException handling.
Connection timeouts and DNS resolution failures now surface as clean
RuntimeError messages instead of raw requests exception tracebacks.

Browser Use managed-gateway mode preserves raw exception propagation
so the existing idempotency-key retry semantics keep working.

Closes #2746

Co-authored-by: teknium1 <127238744+teknium1@users.noreply.github.com>
This commit is contained in:
nidhi-singh02 2026-05-15 01:51:41 -07:00 committed by Teknium
parent 6af9942327
commit 13c72fb486
3 changed files with 68 additions and 48 deletions

View file

@ -137,12 +137,22 @@ class BrowserUseProvider(CloudBrowserProvider):
else {} else {}
) )
response = requests.post( try:
f"{config['base_url']}/browsers", response = requests.post(
headers=headers, f"{config['base_url']}/browsers",
json=payload, headers=headers,
timeout=30, json=payload,
) timeout=30,
)
except requests.RequestException as exc:
# Managed mode: propagate raw so callers can retry with the
# preserved idempotency key. Direct mode: wrap network failures
# into a clean RuntimeError for end users.
if managed_mode:
raise
raise RuntimeError(
f"Browser Use API connection failed: {exc}"
) from exc
if not response.ok: if not response.ok:
if managed_mode and not _should_preserve_pending_create_key(response): if managed_mode and not _should_preserve_pending_create_key(response):

View file

@ -92,45 +92,50 @@ class BrowserbaseProvider(CloudBrowserProvider):
"X-BB-API-Key": config["api_key"], "X-BB-API-Key": config["api_key"],
} }
response = requests.post( try:
f"{config['base_url']}/v1/sessions", response = requests.post(
headers=headers, f"{config['base_url']}/v1/sessions",
json=session_config, headers=headers,
timeout=30, json=session_config,
) timeout=30,
)
proxies_fallback = False proxies_fallback = False
keepalive_fallback = False keepalive_fallback = False
# Handle 402 — paid features unavailable # Handle 402 — paid features unavailable
if response.status_code == 402: if response.status_code == 402:
if enable_keep_alive: if enable_keep_alive:
keepalive_fallback = True keepalive_fallback = True
logger.warning( logger.warning(
"keepAlive may require paid plan (402), retrying without it. " "keepAlive may require paid plan (402), retrying without it. "
"Sessions may timeout during long operations." "Sessions may timeout during long operations."
) )
session_config.pop("keepAlive", None) session_config.pop("keepAlive", None)
response = requests.post( response = requests.post(
f"{config['base_url']}/v1/sessions", f"{config['base_url']}/v1/sessions",
headers=headers, headers=headers,
json=session_config, json=session_config,
timeout=30, timeout=30,
) )
if response.status_code == 402 and enable_proxies: if response.status_code == 402 and enable_proxies:
proxies_fallback = True proxies_fallback = True
logger.warning( logger.warning(
"Proxies unavailable (402), retrying without proxies. " "Proxies unavailable (402), retrying without proxies. "
"Bot detection may be less effective." "Bot detection may be less effective."
) )
session_config.pop("proxies", None) session_config.pop("proxies", None)
response = requests.post( response = requests.post(
f"{config['base_url']}/v1/sessions", f"{config['base_url']}/v1/sessions",
headers=headers, headers=headers,
json=session_config, json=session_config,
timeout=30, timeout=30,
) )
except requests.RequestException as exc:
raise RuntimeError(
f"Browserbase API connection failed: {exc}"
) from exc
if not response.ok: if not response.ok:
raise RuntimeError( raise RuntimeError(

View file

@ -47,12 +47,17 @@ class FirecrawlProvider(CloudBrowserProvider):
body: Dict[str, object] = {"ttl": ttl} body: Dict[str, object] = {"ttl": ttl}
response = requests.post( try:
f"{self._api_url()}/v2/browser", response = requests.post(
headers=self._headers(), f"{self._api_url()}/v2/browser",
json=body, headers=self._headers(),
timeout=30, json=body,
) timeout=30,
)
except requests.RequestException as exc:
raise RuntimeError(
f"Firecrawl API connection failed: {exc}"
) from exc
if not response.ok: if not response.ok:
raise RuntimeError( raise RuntimeError(