feat: Add automatic port checking and cleanup to app.py

Enhanced app.py with port management:
- Added check_port_available() to detect if ports are in use
- Added kill_process_on_port() to automatically free ports
- Checks ports 3001 (backend) and 5173 (frontend) before starting
- Automatically kills existing processes on those ports
- Cross-platform support (Windows netstat/taskkill, Linux lsof/kill)

This fixes the 'EADDRINUSE' error when ports are already occupied.

Benefits:
 No manual port cleanup needed
 Graceful handling of port conflicts
 User-friendly warning messages
 Automatic retry after port cleanup

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
donald
2025-12-06 00:15:52 +08:00
parent ea4108b905
commit d77f997c33

59
app.py
View File

@@ -114,6 +114,51 @@ class AppLauncher:
self.print_info("Copy .env.example to .env and configure it")
return False
def check_port_available(self, port):
"""Check if a port is available"""
import socket
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', port))
return True
except OSError:
return False
def kill_process_on_port(self, port):
"""Kill process using the specified port"""
try:
if self.is_windows:
# Find PID using netstat
result = subprocess.run(
['netstat', '-ano'],
capture_output=True,
text=True,
check=True
)
for line in result.stdout.split('\n'):
if f':{port}' in line and 'LISTENING' in line:
parts = line.split()
if len(parts) >= 5:
pid = parts[-1]
subprocess.run(['taskkill', '/F', '/PID', pid], capture_output=True)
self.print_success(f"Killed existing process on port {port}")
time.sleep(1)
return True
else:
# Unix/Linux
subprocess.run(
['lsof', '-ti', f':{port}', '|', 'xargs', 'kill', '-9'],
shell=True,
capture_output=True
)
self.print_success(f"Killed existing process on port {port}")
time.sleep(1)
return True
except Exception as e:
self.print_warning(f"Could not kill process on port {port}: {str(e)}")
return False
def start_backend(self):
"""Start the backend server"""
self.print_info("Starting backend server...")
@@ -276,6 +321,20 @@ class AppLauncher:
self.print_success("All pre-flight checks passed!\n")
# Check and free ports if needed
backend_port = 3001
frontend_port = 5173
if not self.check_port_available(backend_port):
self.print_warning(f"Port {backend_port} is already in use")
self.print_info("Attempting to free the port...")
self.kill_process_on_port(backend_port)
if not self.check_port_available(frontend_port):
self.print_warning(f"Port {frontend_port} is already in use")
self.print_info("Attempting to free the port...")
self.kill_process_on_port(frontend_port)
# Start services
if not self.start_backend():
self.cleanup()