Skip to content

Commit 225cbac

Browse files
alexzhang13claude
andcommitted
fix: handle BrokenPipeError in LMHandler during parallel execution
When running parallel evaluations, multiple workers connect to the LMHandler socket server. When workers complete and close their sockets, BrokenPipeError was raised during response transmission, causing noisy error output. Changes: - Add _safe_send() helper that catches connection errors silently - Handle BrokenPipeError, ConnectionError, ConnectionResetError, and OSError separately from other exceptions - Use _safe_send() for all socket_send() calls in handle() method This prevents cascading errors where the exception handler tried to send an error response on an already-broken socket. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 37f6d0b commit 225cbac

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

‎rlm/core/lm_handler.py‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def handle(self):
2222
request_data = socket_recv(self.connection)
2323
if not isinstance(request_data, dict):
2424
response = LMResponse.error_response("Request must be a JSON object")
25-
socket_send(self.connection, response.to_dict())
25+
self._safe_send(response)
2626
return
2727

2828
request = LMRequest.from_dict(request_data)
@@ -37,11 +37,26 @@ def handle(self):
3737
else:
3838
response = LMResponse.error_response("Missing 'prompt' or 'prompts' in request.")
3939

40-
socket_send(self.connection, response.to_dict())
40+
self._safe_send(response)
41+
42+
except (BrokenPipeError, ConnectionError, ConnectionResetError, OSError) as e:
43+
# Client disconnected - this is expected during parallel execution
44+
# when workers complete and close their sockets. Silently ignore.
45+
pass
4146

4247
except Exception as e:
48+
# Try to send error response, but don't fail if socket is broken
4349
response = LMResponse.error_response(str(e))
50+
self._safe_send(response)
51+
52+
def _safe_send(self, response: LMResponse) -> bool:
53+
"""Send response, returning False if the socket is broken."""
54+
try:
4455
socket_send(self.connection, response.to_dict())
56+
return True
57+
except (BrokenPipeError, ConnectionError, ConnectionResetError, OSError):
58+
# Client disconnected - silently ignore
59+
return False
4560

4661
def _handle_single(self, request: LMRequest, handler: "LMHandler") -> LMResponse:
4762
"""Handle a single prompt request."""

0 commit comments

Comments
 (0)