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

  1. Inspect the logged error to see whether it is a parse (JSON/schema) error or a send failure.
  2. Log/inspect the raw text frame on the client side and validate it against the expected message schema before sending.
  3. Rebuild/reload the client extension so client and server use the same message protocol version.
  4. 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

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.