diff --git a/backend/src/main.ts b/backend/src/main.ts index ebc80f1..b9cc4a2 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -6,6 +6,15 @@ import { WebSocketServer } from 'ws'; import { TerminalGateway } from './terminal/terminal.gateway'; import { SftpGateway } from './terminal/sftp.gateway'; +// Crash handlers — catch whatever is killing the process +process.on('uncaughtException', (err) => { + console.error(`[FATAL] Uncaught Exception: ${err.message}\n${err.stack}`); +}); + +process.on('unhandledRejection', (reason: any) => { + console.error(`[FATAL] Unhandled Rejection: ${reason?.message || reason}\n${reason?.stack || ''}`); +}); + async function bootstrap() { const app = await NestFactory.create(AppModule); app.setGlobalPrefix('api'); @@ -26,13 +35,21 @@ async function bootstrap() { const sftpWss = new WebSocketServer({ noServer: true }); terminalWss.on('connection', (ws, req) => { - console.log(`[WS] Terminal connection established`); - terminalGateway.handleConnection(ws, req); + try { + console.log(`[WS] Terminal connection established`); + terminalGateway.handleConnection(ws, req); + } catch (err: any) { + console.error(`[FATAL] Terminal handleConnection crashed: ${err.message}\n${err.stack}`); + } }); sftpWss.on('connection', (ws, req) => { - console.log(`[WS] SFTP connection established`); - sftpGateway.handleConnection(ws, req); + try { + console.log(`[WS] SFTP connection established`); + sftpGateway.handleConnection(ws, req); + } catch (err: any) { + console.error(`[FATAL] SFTP handleConnection crashed: ${err.message}\n${err.stack}`); + } }); // Remove ALL existing upgrade listeners (WsAdapter's) so we handle upgrades first @@ -41,24 +58,29 @@ async function bootstrap() { // Our handler runs first — routes terminal/sftp, passes everything else to WsAdapter server.on('upgrade', (req: any, socket: any, head: any) => { - const pathname = req.url?.split('?')[0]; - console.log(`[HTTP-UPGRADE] path=${pathname} socket.destroyed=${socket.destroyed}`); + try { + const pathname = req.url?.split('?')[0]; + console.log(`[HTTP-UPGRADE] path=${pathname} socket.destroyed=${socket.destroyed}`); - if (pathname === '/api/ws/terminal') { - terminalWss.handleUpgrade(req, socket, head, (ws) => { - console.log(`[WS] Terminal upgrade complete`); - terminalWss.emit('connection', ws, req); - }); - } else if (pathname === '/api/ws/sftp') { - sftpWss.handleUpgrade(req, socket, head, (ws) => { - console.log(`[WS] SFTP upgrade complete`); - sftpWss.emit('connection', ws, req); - }); - } else { - // Pass to WsAdapter's original handlers (for RDP etc) - for (const listener of existingListeners) { - listener.call(server, req, socket, head); + if (pathname === '/api/ws/terminal') { + terminalWss.handleUpgrade(req, socket, head, (ws) => { + console.log(`[WS] Terminal upgrade complete`); + terminalWss.emit('connection', ws, req); + }); + } else if (pathname === '/api/ws/sftp') { + sftpWss.handleUpgrade(req, socket, head, (ws) => { + console.log(`[WS] SFTP upgrade complete`); + sftpWss.emit('connection', ws, req); + }); + } else { + // Pass to WsAdapter's original handlers (for RDP etc) + for (const listener of existingListeners) { + listener.call(server, req, socket, head); + } } + } catch (err: any) { + console.error(`[FATAL] Upgrade handler crashed: ${err.message}\n${err.stack}`); + socket.destroy(); } }); }