{"record":{"id":"71baa759b5ae4ab2","repo":"iflytek/astron-agent","slug":"websocketclientrecvlooperror","errorCode":"WebSocketClientRecvLoopError","errorMessage":"{e}","messagePattern":"\\{e\\}","errorType":"error_code","errorClass":"WebSocketClientException","httpStatus":null,"severity":"error","filePath":"core/plugin/aitools/common/clients/websockets_client.py","lineNumber":140,"sourceCode":"                    CodeEnums.WebSocketClientDataFormatError,\n                    extra_message=\"WebSocket 数据格式错误\",\n                )\n\n    async def recv(self) -> AsyncIterator[Any]:\n        \"\"\"Receive data from WebSocket server\"\"\"\n        while self._running:\n            try:\n                msg = await self.recv_queue.get()\n                if msg is None:\n                    break\n                if isinstance(msg, BaseException):\n                    raise msg\n                self.recv_data_list.append(msg)\n                yield msg\n            except WebSocketClientException:\n                raise\n            except Exception as e:\n                raise WebSocketClientException.from_error_code(\n                    CodeEnums.WebSocketClientRecvLoopError, extra_message=str(e)\n                )\n\n    async def _send_loop(self) -> None:\n        \"\"\"Send loop\"\"\"\n        try:\n            while self._running:\n                data = await self.send_queue.get()\n                if data == \"EOF\":\n                    break\n                await self.ws.send(data)\n                await asyncio.sleep(self.send_interval)\n        except websockets.exceptions.ConnectionClosedOK as e:\n            log.info(f\"WebSocket closed normally: {e}\")\n        except websockets.exceptions.ConnectionClosedError as e:\n            await self.recv_queue.put(\n                WebSocketClientException.from_error_code(\n                    CodeEnums.WebSocketClientNotConnectedError, extra_message=str(e)","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/plugin/aitools/common/clients/websockets_client.py#L122-L158","documentation":"WebSocketClientRecvLoopError wraps any unexpected exception raised while iterating received messages in recv(). WebSocketClientException instances are re-raised unchanged; everything else (JSON decode errors, connection drops, KeyError) is wrapped with the original message in extra_message.","triggerScenarios":"Iterating async for msg in client.recv() when the connection drops mid-stream, a received frame is not valid JSON downstream, or any callback/processing in the loop throws.","commonSituations":"Server closes the socket during a long-running stream, network interruption, malformed frames from the server, consumer code inside the async-for body raising and being misattributed to the recv loop.","solutions":["Read extra_message to identify the underlying exception; fix that root cause first.","Wrap the recv loop in reconnect logic that recreates the client on WebSocketClientException.","Check server logs for abrupt disconnections or protocol errors.","Keep processing logic outside the recv iteration or handle its exceptions separately so they are not masked."],"exampleFix":"// before\nasync for msg in client.recv():\n    handle(msg)\n\n// after\ntry:\n    async for msg in client.recv():\n        handle(msg)\nexcept WebSocketClientException as e:\n    logger.warning(f\"recv loop ended: {e}\")\n    await reconnect(client)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    async for msg in client.recv():\n        process(msg)\nexcept WebSocketClientException as e:\n    logger.warning(f\"recv loop terminated: {e}\")\n    await reconnect(client)","preventionTips":["Wrap the whole recv consumption in reconnect logic","Log extra_message to find the wrapped root cause","Monitor connection health with heartbeats/pings","Keep heavy processing out of the recv loop body"],"tags":["websocket","recv","stream"],"backgroundTag":"network-request-failed","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}