{"record":{"id":"26c76cbbddfd3d94","repo":"XX-net/XX-Net","slug":"remove-conn-d-except-r","errorCode":null,"errorMessage":"remove conn:%d except:%r","messagePattern":"remove conn:(.+?) except:%r","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"code/default/x_tunnel/local/proxy_session.py","lineNumber":522,"sourceCode":"        conn_list = dict(self.conn_list)\n        for conn_id in conn_list:\n            try:\n                # xlog.debug(\"stopping conn:%d\", conn_id)\n                self.conn_list[conn_id].stop(reason=\"system reset\")\n            except Exception as e:\n                xlog.warn(\"stopping conn:%d fail:%r\", conn_id, e)\n                pass\n        # self.conn_list = {}\n        xlog.debug(\"stop all connection finished\")\n\n    def remove_conn(self, conn_id):\n        try:\n            if conn_id in self.conn_list:\n                conn = self.conn_list[conn_id]\n                # xlog.debug(\"remove conn:%d %s:%d\", conn_id, conn.host, conn.port)\n                del self.conn_list[conn_id]\n        except Exception as e:\n            xlog.warn(\"remove conn:%d except:%r\", conn_id, e)\n\n        if len(self.conn_list) == 0:\n            self.target_on_roads = 0\n\n    def send_conn_data(self, conn_id, data):\n        if not self.running:\n            xlog.warn(\"send_conn_data but not running\")\n            return\n\n        # xlog.debug(\"upload conn:%d, len:%d\", conn_id, len(data))\n        buf = base_container.WriteBuffer()\n        buf.append(struct.pack(\"<II\", conn_id, len(data)))\n        buf.append(data)\n        self.send_buffer.put(buf)\n\n        if self.oldest_received_time == 0:\n            self.oldest_received_time = time.time()\n        elif self.send_buffer.pool_size > g.config.max_payload:","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/XX-net/XX-Net/blob/cfa5bc17b67676e467f37ec50766127e0ab5f0aa/code/default/x_tunnel/local/proxy_session.py#L504-L540","documentation":"remove_conn deletes a connection from proxy_session.conn_list inside a try/except; any exception during the dict lookup/deletion is caught and logged with the conn_id and repr of the exception, after which the code continues (resetting target_on_roads if the list became empty). It indicates bookkeeping trouble while tearing down a connection, not a data-path failure.","triggerScenarios":"do_stop or connection teardown calling remove_conn for a conn_id whose entry is in an inconsistent state, or concurrent mutation of conn_list raising inside the guarded block (e.g. a custom conn object whose __del__/comparison raises during dict operations).","commonSituations":"Concurrent stop and data-receive threads mutating conn_list; custom/patched connection classes; rare races during rapid churn of short-lived connections.","solutions":["Inspect the exception repr in the log to find which operation inside the try block actually raised.","Serialize conn_list mutation with the session lock if you have patched this code, or upgrade to a version that locks remove_conn.","If it only appears during shutdown races, it is benign; verify fd/socket counts return to baseline afterwards."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    session.remove_conn(conn_id)\nexcept Exception:\n    pass  # logged internally; verify emptiness separately","preventionTips":["Avoid mutating session.conn_list from your own code; use remove_conn.","Serialize teardown paths so remove_conn doesn't race with data handlers."],"tags":["shutdown","concurrency","bookkeeping"],"backgroundTag":"cleanup-on-shutdown-failed","analyzedSha":"cfa5bc17b67676e467f37ec50766127e0ab5f0aa","analyzedAt":"2026-08-27T19:28:28.225Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}