From f36c89cd5798da0f313192555739975e57ffdef5 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Sun, 17 May 2026 04:02:05 -0700 Subject: [PATCH] fix(plugins/browser): carry forward requests.RequestException wrapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #25580 was authored before #2746 landed on main, so its plugin versions of browser_use/browserbase/firecrawl ship without the requests.RequestException → RuntimeError wrapping that 13c72fb4 added to the legacy tools/browser_providers/ files for #2746. Cherry-picking the PR + git rm'ing the legacy files (the migration's intent) would silently revert that network-error fix. Port the same try/except pattern into the three plugin create_session() methods. Browser Use managed-mode keeps its raw-exception propagation (idempotency-key retry semantics). Co-authored-by: nidhi-singh02 --- plugins/browser/browser_use/provider.py | 22 +++++-- plugins/browser/browserbase/provider.py | 77 +++++++++++++------------ plugins/browser/firecrawl/provider.py | 17 ++++-- 3 files changed, 68 insertions(+), 48 deletions(-) diff --git a/plugins/browser/browser_use/provider.py b/plugins/browser/browser_use/provider.py index 8c5af5f9f00..3d371bdd88a 100644 --- a/plugins/browser/browser_use/provider.py +++ b/plugins/browser/browser_use/provider.py @@ -198,12 +198,22 @@ class BrowserUseBrowserProvider(BrowserProvider): else {} ) - response = requests.post( - f"{config['base_url']}/browsers", - headers=headers, - json=payload, - timeout=30, - ) + try: + response = requests.post( + f"{config['base_url']}/browsers", + headers=headers, + 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 managed_mode and not _should_preserve_pending_create_key(response): diff --git a/plugins/browser/browserbase/provider.py b/plugins/browser/browserbase/provider.py index 0d1a646c8a6..2b05d01d03b 100644 --- a/plugins/browser/browserbase/provider.py +++ b/plugins/browser/browserbase/provider.py @@ -139,45 +139,50 @@ class BrowserbaseBrowserProvider(BrowserProvider): "X-BB-API-Key": config["api_key"], } - response = requests.post( - f"{config['base_url']}/v1/sessions", - headers=headers, - json=session_config, - timeout=30, - ) + try: + response = requests.post( + f"{config['base_url']}/v1/sessions", + headers=headers, + json=session_config, + timeout=30, + ) - proxies_fallback = False - keepalive_fallback = False + proxies_fallback = False + keepalive_fallback = False - # Handle 402 — paid features unavailable - if response.status_code == 402: - if enable_keep_alive: - keepalive_fallback = True - logger.warning( - "keepAlive may require paid plan (402), retrying without it. " - "Sessions may timeout during long operations." - ) - session_config.pop("keepAlive", None) - response = requests.post( - f"{config['base_url']}/v1/sessions", - headers=headers, - json=session_config, - timeout=30, - ) + # Handle 402 — paid features unavailable + if response.status_code == 402: + if enable_keep_alive: + keepalive_fallback = True + logger.warning( + "keepAlive may require paid plan (402), retrying without it. " + "Sessions may timeout during long operations." + ) + session_config.pop("keepAlive", None) + response = requests.post( + f"{config['base_url']}/v1/sessions", + headers=headers, + json=session_config, + timeout=30, + ) - if response.status_code == 402 and enable_proxies: - proxies_fallback = True - logger.warning( - "Proxies unavailable (402), retrying without proxies. " - "Bot detection may be less effective." - ) - session_config.pop("proxies", None) - response = requests.post( - f"{config['base_url']}/v1/sessions", - headers=headers, - json=session_config, - timeout=30, - ) + if response.status_code == 402 and enable_proxies: + proxies_fallback = True + logger.warning( + "Proxies unavailable (402), retrying without proxies. " + "Bot detection may be less effective." + ) + session_config.pop("proxies", None) + response = requests.post( + f"{config['base_url']}/v1/sessions", + headers=headers, + json=session_config, + timeout=30, + ) + except requests.RequestException as exc: + raise RuntimeError( + f"Browserbase API connection failed: {exc}" + ) from exc if not response.ok: raise RuntimeError( diff --git a/plugins/browser/firecrawl/provider.py b/plugins/browser/firecrawl/provider.py index 498e4ffad9b..2c605134a01 100644 --- a/plugins/browser/firecrawl/provider.py +++ b/plugins/browser/firecrawl/provider.py @@ -82,12 +82,17 @@ class FirecrawlBrowserProvider(BrowserProvider): body: Dict[str, object] = {"ttl": ttl} - response = requests.post( - f"{self._api_url()}/v2/browser", - headers=self._headers(), - json=body, - timeout=30, - ) + try: + response = requests.post( + f"{self._api_url()}/v2/browser", + headers=self._headers(), + json=body, + timeout=30, + ) + except requests.RequestException as exc: + raise RuntimeError( + f"Firecrawl API connection failed: {exc}" + ) from exc if not response.ok: raise RuntimeError(