diff --git a/browser-service/src/core/browser.py b/browser-service/src/core/browser.py index 8a5eccf..59e978d 100644 --- a/browser-service/src/core/browser.py +++ b/browser-service/src/core/browser.py @@ -202,11 +202,17 @@ # Fall back to Playwright rendering # Separate context for each fetch for isolation - context = await self._browser.new_context( - viewport={'width': 1280, 'height': 800}, - user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36' - ) - page = await context.new_page() + try: + context = await asyncio.wait_for( + self._browser.new_context( + viewport={'width': 1280, 'height': 800}, + user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36' + ), timeout=20.0 + ) + page = await asyncio.wait_for(context.new_page(), timeout=20.0) + except Exception as ce: + logger.warning(f"Browser stall during parallel fetch context: {ce}. Falling back to error state.") + return {"url": url, "success": False, "error": f"Failed to initialize Chromium context locally: {ce}", "fetch_mode": "js"} try: await page.goto(url, wait_until="domcontentloaded", timeout=20000) await asyncio.sleep(1) # Wait for JS dynamic content @@ -236,7 +242,8 @@ "fetch_mode": "js" } finally: - await context.close() + if 'context' in locals(): + await context.close() tasks = [fetch_one(url) for url in urls] return await asyncio.gather(*tasks)