diff --git a/backend/src/app.py b/backend/src/app.py index e15535a1..4c2c4564 100755 --- a/backend/src/app.py +++ b/backend/src/app.py @@ -19,7 +19,7 @@ from pathlib import Path project_root = Path(__file__).resolve().parent.parent.parent from alembic.config import Config as AlembicConfig -from fastapi import FastAPI, HTTPException, Request, WebSocket, WebSocketDisconnect +from fastapi import FastAPI, HTTPException, Request, WebSocket, WebSocketDisconnect, status from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse, JSONResponse from fastapi.staticfiles import StaticFiles @@ -95,6 +95,10 @@ app = FastAPI( version="1.0.0", lifespan=lifespan, ) +# TraceContextMiddleware MUST be the outermost middleware so trace_id +# is seeded before any other middleware or handler runs. +from .core.middleware.trace import TraceContextMiddleware # noqa: E402 +app.add_middleware(TraceContextMiddleware) # #endregion FastAPI_App # #region ensure_initial_admin_user [C:3] [TYPE Function] # @BRIEF Ensures initial admin user exists when bootstrap env flags are enabled. @@ -246,9 +250,16 @@ app.add_middleware(HSTSMiddleware) # appears in our structured JSON log output. @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): + client_host = request.client.host if request.client else "unknown" logger.exception( f"Unhandled exception: {request.method} {request.url.path}", - extra={"src": "app.exception_handler", "path": request.url.path, "method": request.method}, + extra={ + "src": "app.exception_handler", + "path": request.url.path, + "method": request.method, + "query_params": dict(request.query_params), + "client": client_host, + }, ) return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, @@ -296,11 +307,6 @@ async def log_requests(request: Request, call_next): detail="Environment unavailable. Please check if the Superset instance is running.", ) # #endregion log_requests -# Seed trace_id on every request — MUST be the outermost middleware so trace_id -# is seeded before log_requests (or any other middleware) runs. -from .core.middleware.trace import TraceContextMiddleware - -app.add_middleware(TraceContextMiddleware) # #region API_Routes [C:3] [TYPE Block] # @BRIEF Register all FastAPI route groups exposed by the application entrypoint. # @RELATION DEPENDS_ON -> [FastAPI_App] @@ -377,6 +383,7 @@ async def _authenticate_websocket(websocket: WebSocket, endpoint_name: str) -> b ) return True except Exception: + logger.explore("JWT validation failed in WebSocket auth", error="see traceback") pass # Fallback: try API key @@ -398,6 +405,7 @@ async def _authenticate_websocket(websocket: WebSocket, endpoint_name: str) -> b finally: db.close() except Exception: + logger.explore("API key validation failed in WebSocket auth", error="see traceback") pass logger.warning(