fix: remove debug panel close button to keep it always visible
The close button would hide the debug panel with display: none, making it impossible to see debug messages without reloading. Also includes HTTP POST workaround changes for terminal command execution that bypass the WebSocket send issue. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -225,11 +225,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Debug Panel -->
|
<!-- Debug Panel - Always visible for debugging -->
|
||||||
<div id="terminal-debug-panel" style="margin: 20px; padding: 15px; background: #1a1a1a; border: 1px solid #ff6b6b; border-radius: 8px; font-family: monospace; font-size: 12px; color: #e0e0e0;">
|
<div id="terminal-debug-panel" style="margin: 20px; padding: 15px; background: #1a1a1a; border: 1px solid #ff6b6b; border-radius: 8px; font-family: monospace; font-size: 12px; color: #e0e0e0;">
|
||||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
<div style="margin-bottom: 10px;">
|
||||||
<h3 style="margin: 0; color: #ff6b6b;">🐛 Terminal Debug Panel</h3>
|
<h3 style="margin: 0; color: #ff6b6b;">🐛 Terminal Debug Panel</h3>
|
||||||
<button onclick="document.getElementById('terminal-debug-panel').style.display = 'none'" style="background: #ff6b6b; border: none; color: white; padding: 4px 12px; border-radius: 4px; cursor: pointer;">Close</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="terminal-debug-content" style="max-height: 300px; overflow-y: auto;">
|
<div id="terminal-debug-content" style="max-height: 300px; overflow-y: auto;">
|
||||||
<div style="color: #888;">Waiting for terminal activity...</div>
|
<div style="color: #888;">Waiting for terminal activity...</div>
|
||||||
|
|||||||
@@ -893,18 +893,24 @@ class TerminalManager {
|
|||||||
const ws = new WebSocket(wsUrl);
|
const ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
this.debugLog('WS', `WebSocket OPENED for terminal ${terminalId}`);
|
this.debugLog('WS', `✅ WebSocket OPENED for terminal ${terminalId}`);
|
||||||
|
this.debugLog('WS', `Checking if terminal exists in map...`);
|
||||||
|
|
||||||
// Store WebSocket in terminal entry
|
// Store WebSocket in terminal entry
|
||||||
// NOTE: This assumes initializeXTerm() has already been called
|
// NOTE: This assumes initializeXTerm() has already been called
|
||||||
// and this.terminals has the entry
|
// and this.terminals has the entry
|
||||||
const terminal = this.terminals.get(terminalId);
|
const terminal = this.terminals.get(terminalId);
|
||||||
if (terminal) {
|
if (terminal) {
|
||||||
|
this.debugLog('WS', `✅ Terminal found in map, storing WebSocket`);
|
||||||
terminal.ws = ws;
|
terminal.ws = ws;
|
||||||
terminal.ready = false; // Will be set to true when 'ready' message received
|
terminal.ready = false; // Will be set to true when 'ready' message received
|
||||||
this.debugLog('WS', `WebSocket stored in terminal map, waiting for 'ready' message`);
|
this.debugLog('WS', `✅ WebSocket stored in terminal map, waiting for 'ready' message`);
|
||||||
} else {
|
} else {
|
||||||
this.debugLog('ERROR', `CRITICAL: Terminal ${terminalId} not found in map!`, { terminalsInMap: Array.from(this.terminals.keys()) });
|
this.debugLog('ERROR', `❌ CRITICAL: Terminal ${terminalId} not found in map!`);
|
||||||
|
this.debugLog('ERROR', `Available terminals:`, {
|
||||||
|
count: this.terminals.size,
|
||||||
|
ids: Array.from(this.terminals.keys())
|
||||||
|
});
|
||||||
reject(new Error(`Terminal ${terminalId} not initialized`));
|
reject(new Error(`Terminal ${terminalId} not initialized`));
|
||||||
ws.close();
|
ws.close();
|
||||||
return;
|
return;
|
||||||
@@ -932,12 +938,52 @@ class TerminalManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ws.onerror = (error) => {
|
ws.onerror = (error) => {
|
||||||
this.debugLog('ERROR', `WebSocket error for terminal ${terminalId}`, error);
|
this.debugLog('ERROR', `✖✖✖ WebSocket ERROR for terminal ${terminalId} ✖✖✖`, {
|
||||||
|
type: error.type || 'unknown',
|
||||||
|
message: error.message || 'No error message',
|
||||||
|
error: error
|
||||||
|
});
|
||||||
|
this.debugLog('ERROR', `Check browser console (F12) for full error details`);
|
||||||
reject(error);
|
reject(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onclose = (event) => {
|
ws.onclose = (event) => {
|
||||||
this.debugLog('WS', `WebSocket CLOSED for terminal ${terminalId}`, { code: event.code, reason: event.reason, wasClean: event.wasClean });
|
const closeReasons = {
|
||||||
|
1000: 'Normal Closure',
|
||||||
|
1001: 'Endpoint Going Away',
|
||||||
|
1002: 'Protocol Error',
|
||||||
|
1003: 'Unsupported Data',
|
||||||
|
1004: '(Reserved)',
|
||||||
|
1005: 'No Status Received',
|
||||||
|
1006: 'Abnormal Closure (connection dropped)',
|
||||||
|
1007: 'Invalid frame payload data',
|
||||||
|
1008: 'Policy Violation',
|
||||||
|
1009: 'Message Too Big',
|
||||||
|
1010: 'Mandatory Extension',
|
||||||
|
1011: 'Internal Server Error',
|
||||||
|
1015: 'TLS Handshake'
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeReason = closeReasons[event.code] || `Unknown (${event.code})`;
|
||||||
|
|
||||||
|
this.debugLog('ERROR', `🔌 WebSocket CLOSED for terminal ${terminalId}`, {
|
||||||
|
code: event.code,
|
||||||
|
reasonName: closeReason,
|
||||||
|
reason: event.reason || 'None provided',
|
||||||
|
wasClean: event.wasClean,
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
|
if (event.code === 1006) {
|
||||||
|
this.debugLog('ERROR', `💡 Code 1006 means connection was dropped abnormally - check server logs`);
|
||||||
|
this.debugLog('ERROR', `💡 Common causes: server crash, network issue, or timeout`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show terminals currently in map for debugging
|
||||||
|
this.debugLog('ERROR', `Current terminals in map:`, {
|
||||||
|
count: this.terminals.size,
|
||||||
|
ids: Array.from(this.terminals.keys())
|
||||||
|
});
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.debugLog('ERROR', `Exception connecting WebSocket`, error);
|
this.debugLog('ERROR', `Exception connecting WebSocket`, error);
|
||||||
|
|||||||
@@ -172,7 +172,11 @@ class TerminalService {
|
|||||||
// Handle WebSocket ping (respond with pong)
|
// Handle WebSocket ping (respond with pong)
|
||||||
ws.on('ping', () => {
|
ws.on('ping', () => {
|
||||||
console.log(`[TerminalService] Ping received from ${terminalId}`);
|
console.log(`[TerminalService] Ping received from ${terminalId}`);
|
||||||
ws.pong();
|
try {
|
||||||
|
ws.pong();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[TerminalService] Error sending pong:`, error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle WebSocket pong (response to our ping)
|
// Handle WebSocket pong (response to our ping)
|
||||||
@@ -183,14 +187,18 @@ class TerminalService {
|
|||||||
|
|
||||||
// Handle PTY output - send to client
|
// Handle PTY output - send to client
|
||||||
terminal.pty.onData((data) => {
|
terminal.pty.onData((data) => {
|
||||||
console.log(`[TerminalService] PTY data from ${terminalId}: ${data.replace(/\n/g, '\\n').replace(/\r/g, '\\r')}`);
|
try {
|
||||||
if (ws.readyState === ws.OPEN) {
|
console.log(`[TerminalService] PTY data from ${terminalId}: ${data.replace(/\n/g, '\\n').replace(/\r/g, '\\r')}`);
|
||||||
ws.send(JSON.stringify({
|
if (ws.readyState === ws.OPEN) {
|
||||||
type: 'data',
|
ws.send(JSON.stringify({
|
||||||
data: data
|
type: 'data',
|
||||||
}));
|
data: data
|
||||||
} else {
|
}));
|
||||||
console.log(`[TerminalService] Cannot send PTY data - WebSocket not open (state: ${ws.readyState})`);
|
} else {
|
||||||
|
console.log(`[TerminalService] Cannot send PTY data - WebSocket not open (state: ${ws.readyState})`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[TerminalService] ERROR sending PTY data to client:`, error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -199,13 +207,17 @@ class TerminalService {
|
|||||||
console.log(`[TerminalService] PTY EXIT for ${terminalId}: exitCode=${exitCode}, signal=${signal}`);
|
console.log(`[TerminalService] PTY EXIT for ${terminalId}: exitCode=${exitCode}, signal=${signal}`);
|
||||||
this.logCommand(terminalId, null, `Terminal exited: ${exitCode || signal}`);
|
this.logCommand(terminalId, null, `Terminal exited: ${exitCode || signal}`);
|
||||||
|
|
||||||
if (ws.readyState === ws.OPEN) {
|
try {
|
||||||
ws.send(JSON.stringify({
|
if (ws.readyState === ws.OPEN) {
|
||||||
type: 'exit',
|
ws.send(JSON.stringify({
|
||||||
exitCode,
|
type: 'exit',
|
||||||
signal
|
exitCode,
|
||||||
}));
|
signal
|
||||||
ws.close();
|
}));
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[TerminalService] Error sending exit message:`, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.terminals.delete(terminalId);
|
this.terminals.delete(terminalId);
|
||||||
@@ -221,7 +233,12 @@ class TerminalService {
|
|||||||
|
|
||||||
// Handle WebSocket error
|
// Handle WebSocket error
|
||||||
ws.on('error', (error) => {
|
ws.on('error', (error) => {
|
||||||
console.error(`[TerminalService] WebSocket error for terminal ${terminalId}:`, error);
|
console.error(`[TerminalService] ✖✖✖ WebSocket ERROR for terminal ${terminalId} ✖✖✖`);
|
||||||
|
console.error(`[TerminalService] Error:`, error);
|
||||||
|
console.error(`[TerminalService] Message: ${error.message}`);
|
||||||
|
if (error.stack) {
|
||||||
|
console.error(`[TerminalService] Stack: ${error.stack}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send initial welcome message
|
// Send initial welcome message
|
||||||
@@ -239,9 +256,13 @@ class TerminalService {
|
|||||||
|
|
||||||
// Send a ping immediately after ready to ensure connection stays alive
|
// Send a ping immediately after ready to ensure connection stays alive
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (ws.readyState === ws.OPEN) {
|
try {
|
||||||
ws.ping();
|
if (ws.readyState === ws.OPEN) {
|
||||||
console.log(`[TerminalService] Sent ping after ready message`);
|
ws.ping();
|
||||||
|
console.log(`[TerminalService] Sent ping after ready message`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[TerminalService] Error sending ping after ready:`, error);
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user