jlcodes99/cockpit-tools · error
[WS] 处理消息失败: {}
Error message
[WS] 处理消息失败: {} What it means
Logged when handle_client_message(&server, &mut ws_sender, &text) returns Err while processing a Text frame from a client. handle_client_message parses and dispatches client messages and may reply over ws_sender; any failure there (bad payload, unhandled/unknown message type, or failure sending the response frame) surfaces here. Only the failed message is affected — the select! loop continues and the connection stays open.
Source
Thrown at crates/cockpit-core/src/modules/websocket.rs:559
// 发送 Ready 消息
let ready_msg = WsMessage::Ready {
version: env!("CARGO_PKG_VERSION").to_string(),
};
if let Ok(json) = serde_json::to_string(&ready_msg) {
let _ = ws_sender.send(Message::Text(json.into())).await;
}
// 订阅广播
let mut broadcast_rx = server.tx.subscribe();
loop {
tokio::select! {
// 接收客户端消息
msg = ws_receiver.next() => {
match msg {
Some(Ok(Message::Text(text))) => {
if let Err(e) = handle_client_message(&server, &mut ws_sender, &text).await {
crate::modules::logger::log_error(&format!("[WS] 处理消息失败: {}", e));
}
}
Some(Ok(Message::Close(_))) => {
crate::modules::logger::log_info(&format!("[WS] 客户端断开: {}", addr));
break;
}
Some(Err(e)) => {
crate::modules::logger::log_error(&format!("[WS] 接收错误 {}: {}", addr, e));
break;
}
None => break,
_ => {}
}
}
// 发送广播消息
msg = broadcast_rx.recv() => {
if let Ok(json) = msg {
if ws_sender.send(Message::Text(json.into())).await.is_err() {View on GitHub (pinned to 1ed8b77992)
Solutions
- Inspect the logged error to see whether it is a parse (JSON/schema) error or a send failure.
- Log/inspect the raw text frame on the client side and validate it against the expected message schema before sending.
- Rebuild/reload the client extension so client and server use the same message protocol version.
- If it is a send error, treat it as a disconnect: close and reconnect the client socket.
Example fix
// before: sending an unversioned/unknown payload
ws.send(JSON.stringify({ cmd: "startThing" }))
// after: match the expected schema with a known type field
ws.send(JSON.stringify({ type: "start", payload: { id: 1 } })) Defensive patterns
Strategy: try-catch
Validate before calling
// client side: validate the message before sending
function isValidMessage(m) {
return typeof m === "object" && m !== null
&& typeof m.type === "string" && m.type.length > 0;
}
const msg = { type: "start", payload: { id: 1 } };
if (!isValidMessage(msg)) throw new Error("invalid WS message");
ws.send(JSON.stringify(msg)); Type guard
fn is_known_type(t: &str) -> bool {
matches!(t, "start" | "stop" | "status" | "config")
} Try / catch
match handle_client_message(&server, &mut ws_sender, &text).await {
Ok(()) => {}
Err(e) => {
log_error(&format!("[WS] 处理消息失败: {}", e));
// keep the connection open; optionally send an error frame back to the client
let _ = ws_sender.send(Message::Text(format!("{{\"error\":\"{}\"}}", e))).await;
}
} Prevention
- Version the WS message schema and validate payloads on both sides before dispatch.
- Keep a single shared definition of message types between extension and backend.
- Log the offending raw text at debug level to speed up schema-mismatch diagnosis.
- Send an explicit error frame to the client instead of silently dropping bad messages.
When it happens
Trigger: A client sends a Message::Text whose content cannot be handled: invalid JSON, missing/unknown message type field, a request referencing nonexistent state, or the response write on ws_sender fails because the client already went away.
Common situations: A VS Code/extension client and backend disagreeing on the message schema after a version change; hand-written test clients sending malformed JSON; clients disconnecting mid-request so the reply send fails; typos in the message 'type' field.
Related errors
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/c4a8c6be5b5df444.
Report an issue: GitHub.