Spaces:
Paused
Paused
| # --- browser_utils/initialization/debug.py --- | |
| import logging | |
| from playwright.async_api import Page as AsyncPage | |
| logger = logging.getLogger("AIStudioProxyServer") | |
| def setup_debug_listeners(page: AsyncPage) -> None: | |
| """ | |
| Setup console and network logging listeners for comprehensive error snapshots. | |
| This function attaches event listeners to capture: | |
| - Browser console messages (log, warning, error, etc.) | |
| - Network requests and responses | |
| Args: | |
| page: Playwright page instance to attach listeners to | |
| """ | |
| from datetime import datetime, timezone | |
| from api_utils.server_state import state | |
| def handle_console(msg): | |
| """Handle console messages from the browser.""" | |
| try: | |
| # Extract location info if available | |
| location_str = "" | |
| if msg.location: | |
| url = msg.location.get("url", "") | |
| line = msg.location.get("lineNumber", 0) | |
| if url or line: | |
| location_str = f"{url}:{line}" | |
| state.console_logs.append( | |
| { | |
| "timestamp": datetime.now(timezone.utc).isoformat(), | |
| "type": msg.type, | |
| "text": msg.text, | |
| "location": location_str, | |
| } | |
| ) | |
| # Log errors to our logger as well | |
| if msg.type == "error": | |
| # Filter out known benign browser warnings - log at DEBUG level | |
| text_lower = msg.text.lower() | |
| if "cookie" in text_lower and "rejected" in text_lower: | |
| # Known Google cookie warning (SIDCC, etc.) - benign but may indicate stale auth profile | |
| # Log at DEBUG to reduce noise but preserve for troubleshooting | |
| logger.debug( | |
| f"[Browser Cookie Warning] {msg.text} - This may indicate the auth profile needs refresh" | |
| ) | |
| return | |
| logger.warning(f"[Browser Console Error] {msg.text}") | |
| except Exception as e: | |
| logger.error(f"Failed to capture console message: {e}") | |
| def handle_request(request): | |
| """Handle network requests.""" | |
| try: | |
| # Only log relevant requests (skip static assets, images, etc.) | |
| url_lower = request.url.lower() | |
| if any( | |
| ext in url_lower | |
| for ext in [".png", ".jpg", ".jpeg", ".gif", ".css", ".woff", ".woff2"] | |
| ): | |
| return # Skip static assets | |
| state.network_log["requests"].append( | |
| { | |
| "timestamp": datetime.now(timezone.utc).isoformat(), | |
| "url": request.url, | |
| "method": request.method, | |
| "resource_type": request.resource_type, | |
| } | |
| ) | |
| except Exception as e: | |
| logger.error(f"Failed to capture network request: {e}") | |
| def handle_response(response): | |
| """Handle network responses.""" | |
| try: | |
| # Only log relevant responses | |
| url_lower = response.url.lower() | |
| if any( | |
| ext in url_lower | |
| for ext in [".png", ".jpg", ".jpeg", ".gif", ".css", ".woff", ".woff2"] | |
| ): | |
| return # Skip static assets | |
| state.network_log["responses"].append( | |
| { | |
| "timestamp": datetime.now(timezone.utc).isoformat(), | |
| "url": response.url, | |
| "status": response.status, | |
| "status_text": response.status_text, | |
| } | |
| ) | |
| except Exception as e: | |
| logger.error(f"Failed to capture network response: {e}") | |
| # Attach listeners | |
| page.on("console", handle_console) | |
| page.on("request", handle_request) | |
| page.on("response", handle_response) | |
| logger.debug("Debug listeners (console + network) attached to page") | |