diff --git a/app/core/plugin_error_handler.py b/app/core/plugin_error_handler.py index f1bb496..1d41aa7 100644 --- a/app/core/plugin_error_handler.py +++ b/app/core/plugin_error_handler.py @@ -2,7 +2,8 @@ import logging import functools import inspect -from fastapi import UploadFile as _UploadFile # noqa: F401 — needed for ForwardRef resolution +from fastapi import UploadFile # noqa: F401 — needed for ForwardRef resolution +from fastapi import WebSocket # noqa: F401 — needed for ForwardRef resolution of WebSocket params from fastapi.responses import JSONResponse logger = logging.getLogger(__name__) diff --git a/app/main.py b/app/main.py index 2fcebd8..c42835e 100644 --- a/app/main.py +++ b/app/main.py @@ -11,6 +11,7 @@ from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse, JSONResponse from fastapi.staticfiles import StaticFiles from starlette.middleware.base import BaseHTTPMiddleware +from starlette.routing import WebSocketRoute import importlib import logging import os @@ -434,8 +435,12 @@ def create_app() -> FastAPI: try: router_module = importlib.import_module(route_def.module) router = getattr(router_module, route_def.router_attr) - # Wrap each route handler with plugin error isolation + # Wrap each HTTP route handler with plugin error isolation + # Skip WebSocket routes — the wrapper breaks WS parameter + # resolution and returns JSONResponse instead of WS close. for route in router.routes: + if isinstance(route, WebSocketRoute): + continue if hasattr(route, 'endpoint'): route.endpoint = wrap_plugin_route(route.endpoint) # Add active-plugin check as a router-level dependency