{"record":{"id":"ce2d47b20df7b0f5","repo":"jd-opensource/joyagent-jdgenie","slug":"str-e","errorCode":null,"errorMessage":"网络连接失败: {str(e)}","messagePattern":"网络连接失败: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"genie-client/app/client.py","lineNumber":149,"sourceCode":"            # 创建客户端会话\n            self._session_context = ClientSession(*streams)\n            session = await self._session_context.__aenter__()\n            logger.debug(f\"[{connection_id}] 客户端会话已创建\")\n\n            # 初始化会话，可能触发认证验证\n            await session.initialize()\n            logger.info(f\"[{connection_id}] SSE连接建立成功\")\n\n            yield session\n\n        except Exception as e:\n            # 根据异常类型进行不同的处理\n            if self._is_authentication_error(e):\n                logger.error(f\"[{connection_id}] 认证失败 - 401 未授权\")\n                raise Exception(\"认证失败 - 无效的凭据\") from e\n            elif self._is_network_error(e):\n                logger.error(f\"[{connection_id}] 网络连接失败: {str(e)}\")\n                raise Exception(f\"网络连接失败: {str(e)}\") from e\n            else:\n                logger.error(f\"[{connection_id}] SSE连接失败: {str(e)}\")\n                raise\n        finally:\n            # 确保资源被正确清理\n            await self._cleanup_connection(connection_id)\n\n    @staticmethod\n    def _is_authentication_error(exception: Exception) -> bool:\n        \"\"\"\n        检查异常是否为认证错误 (401 Unauthorized)\n\n        Args:\n            exception: 待检查的异常对象\n\n        Returns:\n            bool: 如果是认证错误返回True，否则返回False\n        \"\"\"","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/jd-opensource/joyagent-jdgenie/blob/2417e0b8b636d941ad5fb14c59b20dddfef5375d/genie-client/app/client.py#L131-L167","documentation":"Raised by `_sse_connection` when the underlying HTTP/SSE transport raises a network-class error (per `_is_network_error`), such as connection refused, DNS failure, or timeout while opening the SSE stream. The client wraps it into a friendlier message but preserves the cause via `from e`.","triggerScenarios":"ping_server, list_tools, or call_tool attempts an SSE connection while the server host is unreachable: wrong port, server down, DNS failure, firewall, or TLS/network timeout.","commonSituations":"MCP server not started; server_url typo (wrong host/port/scheme); docker network isolation; proxy blocking long-lived SSE connections; VPN down.","solutions":["Confirm the MCP server is running and reachable: curl/telnet the server_url host and port","Check server_url for typos (scheme, host, port) in the client configuration","Check firewall/proxy rules allow the connection and long-lived streaming responses","If it's flaky infrastructure, retry with backoff; the finally-block cleans up the half-open connection"],"exampleFix":"// before\nclient = SseClient(server_url=\"http://localhost:8080\")  # server actually on 8000\n// after\nclient = SseClient(server_url=\"http://localhost:8000\")","handlingStrategy":"retry","validationCode":"import socket\nhost, port = parse_host_port(server_url)\nsocket.create_connection((host, port), timeout=3).close()  # raises if unreachable","typeGuard":"def server_reachable(url: str) -> bool:\n    try:\n        host, port = parse_host_port(url)\n        socket.create_connection((host, port), timeout=3).close()\n        return True\n    except OSError:\n        return False","tryCatchPattern":"for attempt in range(3):\n    try:\n        return await client.ping_server()\n    except Exception as e:\n        if \"网络连接失败\" in str(e):\n            await asyncio.sleep(2 ** attempt)\n        else:\n            raise","preventionTips":["Add a startup reachability check before using the client","Pin the server host/port in one config place and validate it","Monitor server uptime; alert before clients start failing"],"tags":["network","sse","connectivity"],"backgroundTag":"connection-refused","analyzedSha":"2417e0b8b636d941ad5fb14c59b20dddfef5375d","analyzedAt":"2026-09-08T11:28:19.414Z","contentChangedAt":"2026-09-08T11:28:19.414Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}