Fix loading state bugs and server crash
Backend fixes: - Fix server crash when logging large session_state messages (186 agents) - Use safe logging that extracts only message/stack properties - Prevents TypeError in util.inspect on circular refs or deep objects Frontend loading state fixes: - Add reactive WebSocket update to prevent stale session.ws references - Add timeout/retry wrapper for session_state loading (3 retries × 15s) - Add hasEverReceivedSessionState flag to track cached data across reconnects - Implement data-aware loading (isInitialLoad vs isRevalidating) - Show reconnecting badge instead of hiding agents on reconnect Debug improvements: - Add detailed connection state logging in useAggregatedAgents - Add connection status logging in AgentInputArea - Track connecting reasons for easier debugging Fixes: - Agent screen no longer shows false "Offline" toast on reconnect - Home screen shows loading immediately (no empty state flash) - Home screen keeps agents visible during reconnect with badge - Stuck loading has timeout protection with graceful degradation - Server no longer crashes when sending session_state with many agents 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -135,7 +135,10 @@ export class VoiceAssistantWebSocketServer {
|
||||
|
||||
// Set up error handler
|
||||
ws.on("error", async (error) => {
|
||||
console.error(`[WS] Client error:`, error);
|
||||
// Safe error logging
|
||||
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
const errorStack = error instanceof Error ? error.stack : undefined;
|
||||
console.error(`[WS] Client error:`, { message: errorMessage, stack: errorStack });
|
||||
const session = this.sessions.get(ws);
|
||||
if (!session) return;
|
||||
|
||||
@@ -162,7 +165,14 @@ export class VoiceAssistantWebSocketServer {
|
||||
// Validate with Zod
|
||||
const message = WSInboundMessageSchema.parse(parsed);
|
||||
|
||||
console.log(`[WS] Received message type: ${message.type}`, message);
|
||||
// Safe logging that handles large objects without crashing
|
||||
const messageSummary = {
|
||||
type: message.type,
|
||||
...(message.type === "session" && message.message ? {
|
||||
sessionMessageType: message.message.type,
|
||||
} : {}),
|
||||
};
|
||||
console.log(`[WS] Received message:`, messageSummary);
|
||||
|
||||
// Handle WebSocket-level messages
|
||||
switch (message.type) {
|
||||
@@ -198,8 +208,13 @@ export class VoiceAssistantWebSocketServer {
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[WS] Failed to parse/handle message:", error);
|
||||
// Safe error logging - avoid crashing on large/circular objects
|
||||
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
const errorStack = error instanceof Error ? error.stack : undefined;
|
||||
console.error("[WS] Failed to parse/handle message:", {
|
||||
message: errorMessage,
|
||||
stack: errorStack,
|
||||
});
|
||||
// Send error to client
|
||||
this.sendToClient(
|
||||
ws,
|
||||
|
||||
Reference in New Issue
Block a user