Add web server error handling and proper shutdown
- Add stop() method to WebServer class - Store server instance for graceful shutdown - Add error handling in start_server() with user-friendly alert - Show warning dialog if server fails to start (e.g., port in use) - Stop server in closeEvent before application exit - Add status bar messages for server state 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -330,14 +330,48 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def start_server(self):
|
def start_server(self):
|
||||||
"""Start the web server in a background thread."""
|
"""Start the web server in a background thread."""
|
||||||
self.web_server.create_app()
|
self.server_error = None
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
self.web_server.run()
|
try:
|
||||||
|
self.web_server.create_app()
|
||||||
|
self.web_server.run()
|
||||||
|
except Exception as e:
|
||||||
|
self.server_error = str(e)
|
||||||
|
# Emit signal to show error on main thread
|
||||||
|
QTimer.singleShot(0, self.show_server_error)
|
||||||
|
|
||||||
self.server_thread = threading.Thread(target=run, daemon=True)
|
self.server_thread = threading.Thread(target=run, daemon=True)
|
||||||
self.server_thread.start()
|
self.server_thread.start()
|
||||||
self.status_bar.showMessage(f"Server running on port {DEFAULT_PORT}")
|
|
||||||
|
# Give the server a moment to start, then check for errors
|
||||||
|
QTimer.singleShot(1000, self.check_server_started)
|
||||||
|
|
||||||
|
def check_server_started(self):
|
||||||
|
"""Check if server started successfully."""
|
||||||
|
if self.server_error:
|
||||||
|
self.show_server_error()
|
||||||
|
else:
|
||||||
|
self.status_bar.showMessage(f"Server running on port {DEFAULT_PORT}")
|
||||||
|
|
||||||
|
def show_server_error(self):
|
||||||
|
"""Show server error dialog."""
|
||||||
|
error_msg = self.server_error or "Unknown error"
|
||||||
|
self.status_bar.showMessage(f"Server failed to start")
|
||||||
|
QMessageBox.warning(
|
||||||
|
self,
|
||||||
|
"Web Server Error",
|
||||||
|
f"Failed to start web server on port {DEFAULT_PORT}.\n\n"
|
||||||
|
f"Error: {error_msg}\n\n"
|
||||||
|
"The web interface will not be available.\n"
|
||||||
|
"Check if another application is using the port."
|
||||||
|
)
|
||||||
|
|
||||||
|
def stop_server(self):
|
||||||
|
"""Stop the web server."""
|
||||||
|
if self.web_server:
|
||||||
|
self.web_server.stop()
|
||||||
|
self.status_bar.showMessage("Server stopped")
|
||||||
|
|
||||||
def update_ip_label(self):
|
def update_ip_label(self):
|
||||||
"""Update the IP address label."""
|
"""Update the IP address label."""
|
||||||
@@ -510,7 +544,12 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
"""Handle window close."""
|
"""Handle window close."""
|
||||||
|
# Stop the web server
|
||||||
|
self.stop_server()
|
||||||
|
|
||||||
|
# Hide tray icon
|
||||||
self.tray_icon.hide()
|
self.tray_icon.hide()
|
||||||
|
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
def resizeEvent(self, event):
|
def resizeEvent(self, event):
|
||||||
|
|||||||
@@ -254,8 +254,13 @@ class WebServer:
|
|||||||
port=self.port,
|
port=self.port,
|
||||||
log_level="warning"
|
log_level="warning"
|
||||||
)
|
)
|
||||||
server = uvicorn.Server(config)
|
self.server = uvicorn.Server(config)
|
||||||
server.run()
|
self.server.run()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Stop the web server."""
|
||||||
|
if self.server:
|
||||||
|
self.server.should_exit = True
|
||||||
|
|
||||||
async def run_async(self):
|
async def run_async(self):
|
||||||
"""Run the web server asynchronously."""
|
"""Run the web server asynchronously."""
|
||||||
|
|||||||
Reference in New Issue
Block a user