realtime / runtime /error_handler.py
teganmosi
Fix WebSocketDisconnect tracebacks and handle closed receives gracefully
d570cd7
Raw
History Blame Contribute Delete
2.02 kB
import logging
from typing import Any
from models.event import EventType
from models.session_state import TurnState
logger = logging.getLogger("s2s_server")
class ErrorHandler:
def __init__(self, context: Any):
self.context = context
async def handle_error(self, error: Exception, context_msg: str = ""):
from fastapi import WebSocketDisconnect
is_disconnect = isinstance(error, WebSocketDisconnect) or (
isinstance(error, RuntimeError) and "once a disconnect message has been received" in str(error)
)
if is_disconnect:
self.context.logger.info(
f"[{self.context.session_id}] Connection closed by client during {context_msg}."
)
else:
self.context.logger.error(
f"[{self.context.session_id}] ErrorHandler caught exception during {context_msg}: {error}",
exc_info=True
)
# Publish service error event
await self.context.event_bus.publish(EventType.SERVICE_ERROR, {
"error": str(error),
"context": context_msg
})
# Notify the client of the error (only if still connected)
if not is_disconnect:
try:
await self.context.websocket.send_json({
"type": "error",
"message": f"Service error during {context_msg}. The system is resetting."
})
await self.context.websocket.send_json({"type": "done"})
except Exception as ws_err:
self.context.logger.error(
f"[{self.context.session_id}] Failed to send error frame to WebSocket: {ws_err}"
)
# Trigger cleanup
self.context.cleanup_manager.perform_cleanup()
# Reset turn manager to idle
if self.context.turn_manager:
self.context.turn_manager.state = TurnState.IDLE
await self.context.event_bus.publish(EventType.TURN_COMPLETED)