debug(terminal): add comprehensive logging to WebSocket terminal handler

This commit is contained in:
Fusion
2026-05-21 11:01:32 +02:00
parent 55c4dc1281
commit 520078fd64
+11
View File
@@ -1,5 +1,6 @@
"""WebSocket terminal endpoint for tool instances.""" """WebSocket terminal endpoint for tool instances."""
import logging
import uuid import uuid
from fastapi import APIRouter, Depends, HTTPException, WebSocket, WebSocketDisconnect, status from fastapi import APIRouter, Depends, HTTPException, WebSocket, WebSocketDisconnect, status
@@ -10,6 +11,7 @@ from src.models.tool_instance import ToolInstance
from src.services.terminal_manager import terminal_manager from src.services.terminal_manager import terminal_manager
router = APIRouter() router = APIRouter()
logger = logging.getLogger(__name__)
@router.websocket( @router.websocket(
@@ -32,35 +34,42 @@ async def terminal_websocket(
Returns: Returns:
None. Communicates via WebSocket messages. None. Communicates via WebSocket messages.
""" """
logger.info("Terminal WebSocket connection attempt for instance %s", instance_id)
await websocket.accept() await websocket.accept()
try: try:
# Parse instance_id # Parse instance_id
instance_uuid = uuid.UUID(instance_id) instance_uuid = uuid.UUID(instance_id)
except ValueError: except ValueError:
logger.error("Invalid instance ID: %s", instance_id)
await websocket.close(code=4001, reason="Invalid instance ID") await websocket.close(code=4001, reason="Invalid instance ID")
return return
# Authenticate user from session cookie # Authenticate user from session cookie
user_id = await _get_user_from_websocket(websocket, db_session) user_id = await _get_user_from_websocket(websocket, db_session)
if user_id is None: if user_id is None:
logger.warning("Unauthorized terminal access attempt for instance %s", instance_id)
await websocket.close(code=4003, reason="Unauthorized") await websocket.close(code=4003, reason="Unauthorized")
return return
# Get instance and verify ownership # Get instance and verify ownership
instance = await db_session.get(ToolInstance, instance_uuid) instance = await db_session.get(ToolInstance, instance_uuid)
if instance is None: if instance is None:
logger.warning("Instance %s not found", instance_id)
await websocket.close(code=4004, reason="Instance not found") await websocket.close(code=4004, reason="Instance not found")
return return
if instance.owner_id != user_id: if instance.owner_id != user_id:
logger.warning("Forbidden terminal access for instance %s by user %s", instance_id, user_id)
await websocket.close(code=4003, reason="Forbidden") await websocket.close(code=4003, reason="Forbidden")
return return
if instance.status != "running" or not instance.container_id: if instance.status != "running" or not instance.container_id:
logger.warning("Instance %s not running (status=%s, container_id=%s)", instance_id, instance.status, instance.container_id)
await websocket.close(code=4004, reason="Instance not running") await websocket.close(code=4004, reason="Instance not running")
return return
logger.info("Creating terminal session for instance %s (container_id=%s)", instance_id, instance.container_id)
# Create terminal session # Create terminal session
try: try:
session = await terminal_manager.create_session( session = await terminal_manager.create_session(
@@ -68,6 +77,7 @@ async def terminal_websocket(
instance.container_id, instance.container_id,
websocket, websocket,
) )
logger.info("Terminal session created successfully for instance %s", instance_id)
# Send connected status # Send connected status
await websocket.send_json({"type": "status", "status": "connected"}) await websocket.send_json({"type": "status", "status": "connected"})
@@ -84,6 +94,7 @@ async def terminal_websocket(
break break
except Exception as exc: except Exception as exc:
logger.error("Terminal session error for instance %s: %s", instance_id, str(exc), exc_info=True)
await websocket.close(code=4000, reason=f"Error: {exc}") await websocket.close(code=4000, reason=f"Error: {exc}")
finally: finally:
# Cleanup will be handled by the session manager # Cleanup will be handled by the session manager