Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion template/server/messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,43 @@ async def _receive_message(self):

try:
async for message in self._ws:
await self._process_message(json.loads(message))
try:
data = json.loads(message)
await self._process_message(data)
except (ConnectionClosedError, WebSocketException):
# Connection-level failures are handled below and must
# terminate the receive loop so ongoing executions are
# cancelled instead of hanging forever.
raise
except Exception as e:
# A single malformed or unexpected message must not kill
# the receive loop nor be silently swallowed. Log the full
# stack trace together with the raw message so it can be
# diagnosed, and notify the affected execution so it does
# not hang waiting for results.
logger.exception(
"Error while processing WebSocket message: %s (message: %s)",
e,
message[:500],
)
parent_msg_id = None
try:
parent_msg_id = json.loads(message).get(
"parent_header", {}
).get("msg_id")
except Exception:
pass
Comment on lines +448 to +454

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge End active executions when no parent ID can be recovered

When malformed JSON—or a valid message missing parent_header—is received while an execution is active, this recovery attempt leaves parent_msg_id unset and then continues the receive loop without queuing any terminal marker. If the discarded frame was the execution's final idle status, _wait_for_result() emits keepalives indefinitely; previously the outer finally ended the request with a WebSocket error. Fail the active execution(s), or terminate the receive loop, when the malformed message cannot be associated with a parent.

Useful? React with 👍 / 👎.

if parent_msg_id:
execution = self._executions.get(parent_msg_id)
if execution:
await execution.queue.put(
Error(
name="MessageProcessingError",
value=f"Failed to process kernel message: {e}",
traceback="",
)
)
await execution.queue.put(EndOfExecution())
except Exception as e:
logger.error(f"WebSocket received error while receiving messages: {str(e)}")
finally:
Expand Down