refactor: enhance init.sh and server startup error handling

- Refactored init.sh to introduce a reusable function for killing processes on specified ports, improving code clarity and maintainability.
- Added a cleanup function to ensure proper resource management on exit.
- Updated server startup logic in index.ts to handle port conflicts gracefully, providing clear error messages and suggestions for resolution.
- Improved logging for server status and health checks during initialization.
This commit is contained in:
Cody Seibert
2025-12-13 22:06:53 -05:00
parent 7f5cdc0345
commit 13e3f05a7a
2 changed files with 124 additions and 51 deletions

View File

@@ -322,26 +322,58 @@ terminalWss.on(
} }
); );
// Start server // Start server with error handling for port conflicts
server.listen(PORT, () => { const startServer = (port: number) => {
server.listen(port, () => {
const terminalStatus = isTerminalEnabled() const terminalStatus = isTerminalEnabled()
? isTerminalPasswordRequired() ? isTerminalPasswordRequired()
? "enabled (password protected)" ? "enabled (password protected)"
: "enabled" : "enabled"
: "disabled"; : "disabled";
const portStr = port.toString().padEnd(4);
console.log(` console.log(`
╔═══════════════════════════════════════════════════════╗ ╔═══════════════════════════════════════════════════════╗
║ Automaker Backend Server ║ ║ Automaker Backend Server ║
╠═══════════════════════════════════════════════════════╣ ╠═══════════════════════════════════════════════════════╣
║ HTTP API: http://localhost:${PORT} ║ HTTP API: http://localhost:${portStr}
║ WebSocket: ws://localhost:${PORT}/api/events ║ WebSocket: ws://localhost:${portStr}/api/events ║
║ Terminal: ws://localhost:${PORT}/api/terminal/ws ║ Terminal: ws://localhost:${portStr}/api/terminal/ws ║
║ Health: http://localhost:${PORT}/api/health ║ Health: http://localhost:${portStr}/api/health ║
║ Terminal: ${terminalStatus.padEnd(37)} ║ Terminal: ${terminalStatus.padEnd(37)}
╚═══════════════════════════════════════════════════════╝ ╚═══════════════════════════════════════════════════════╝
`); `);
}); });
server.on("error", (error: NodeJS.ErrnoException) => {
if (error.code === "EADDRINUSE") {
console.error(`
╔═══════════════════════════════════════════════════════╗
║ ❌ ERROR: Port ${port} is already in use ║
╠═══════════════════════════════════════════════════════╣
║ Another process is using this port. ║
║ ║
║ To fix this, try one of: ║
║ ║
║ 1. Kill the process using the port: ║
║ lsof -ti:${port} | xargs kill -9 ║
║ ║
║ 2. Use a different port: ║
║ PORT=${port + 1} npm run dev:server ║
║ ║
║ 3. Use the init.sh script which handles this: ║
║ ./init.sh ║
╚═══════════════════════════════════════════════════════╝
`);
process.exit(1);
} else {
console.error("[Server] Error starting server:", error);
process.exit(1);
}
});
};
startServer(PORT);
// Graceful shutdown // Graceful shutdown
process.on("SIGTERM", () => { process.on("SIGTERM", () => {
console.log("SIGTERM received, shutting down..."); console.log("SIGTERM received, shutting down...");

87
init.sh
View File

@@ -33,13 +33,72 @@ fi
echo -e "${YELLOW}Checking Playwright browsers...${NC}" echo -e "${YELLOW}Checking Playwright browsers...${NC}"
npx playwright install chromium 2>/dev/null || true npx playwright install chromium 2>/dev/null || true
# Function to kill process on a port and wait for it to be freed
kill_port() {
local port=$1
local pids=$(lsof -ti:$port 2>/dev/null)
if [ -n "$pids" ]; then
echo -e "${YELLOW}Killing process(es) on port $port: $pids${NC}"
echo "$pids" | xargs kill -9 2>/dev/null || true
# Wait for port to be freed (max 5 seconds)
local retries=0
while [ $retries -lt 10 ]; do
if ! lsof -ti:$port >/dev/null 2>&1; then
echo -e "${GREEN}✓ Port $port is now free${NC}"
return 0
fi
sleep 0.5
retries=$((retries + 1))
done
echo -e "${RED}Warning: Port $port may still be in use${NC}"
return 1
else
echo -e "${GREEN}✓ Port $port is available${NC}"
return 0
fi
}
# Kill any existing processes on required ports # Kill any existing processes on required ports
echo -e "${YELLOW}Checking for processes on ports 3007 and 3008...${NC}" echo -e "${YELLOW}Checking for processes on ports 3007 and 3008...${NC}"
lsof -ti:3007 | xargs kill -9 2>/dev/null || true kill_port 3007
lsof -ti:3008 | xargs kill -9 2>/dev/null || true kill_port 3008
echo ""
# Start the backend server # Prompt user for application mode
echo "═══════════════════════════════════════════════════════"
echo " Select Application Mode:"
echo "═══════════════════════════════════════════════════════"
echo " 1) Web Application (Browser)"
echo " 2) Desktop Application (Electron)"
echo "═══════════════════════════════════════════════════════"
echo ""
SERVER_PID=""
# Cleanup function
cleanup() {
echo 'Cleaning up...'
if [ -n "$SERVER_PID" ]; then
kill $SERVER_PID 2>/dev/null || true
fi
exit
}
trap cleanup INT TERM EXIT
while true; do
read -p "Enter your choice (1 or 2): " choice
case $choice in
1)
echo ""
echo -e "${BLUE}Launching Web Application...${NC}"
# Start the backend server (only needed for Web mode)
echo -e "${BLUE}Starting backend server on port 3008...${NC}" echo -e "${BLUE}Starting backend server on port 3008...${NC}"
mkdir -p logs
npm run dev:server > logs/server.log 2>&1 & npm run dev:server > logs/server.log 2>&1 &
SERVER_PID=$! SERVER_PID=$!
@@ -70,23 +129,6 @@ if [ "$SERVER_READY" = false ]; then
fi fi
echo -e "${GREEN}✓ Server is ready!${NC}" echo -e "${GREEN}✓ Server is ready!${NC}"
echo ""
# Prompt user for application mode
echo "═══════════════════════════════════════════════════════"
echo " Select Application Mode:"
echo "═══════════════════════════════════════════════════════"
echo " 1) Web Application (Browser)"
echo " 2) Desktop Application (Electron)"
echo "═══════════════════════════════════════════════════════"
echo ""
while true; do
read -p "Enter your choice (1 or 2): " choice
case $choice in
1)
echo ""
echo -e "${BLUE}Launching Web Application...${NC}"
echo "The application will be available at: ${GREEN}http://localhost:3007${NC}" echo "The application will be available at: ${GREEN}http://localhost:3007${NC}"
echo "" echo ""
npm run dev:web npm run dev:web
@@ -95,6 +137,8 @@ while true; do
2) 2)
echo "" echo ""
echo -e "${BLUE}Launching Desktop Application...${NC}" echo -e "${BLUE}Launching Desktop Application...${NC}"
echo -e "${YELLOW}(Electron will start its own backend server)${NC}"
echo ""
npm run dev:electron npm run dev:electron
break break
;; ;;
@@ -103,6 +147,3 @@ while true; do
;; ;;
esac esac
done done
# Cleanup on exit
trap "echo 'Cleaning up...'; kill $SERVER_PID 2>/dev/null || true; exit" INT TERM EXIT