feat: FlowPilot AI — Phases 4 & 5 (Gallery, Export, Responsive, Enterprise, Analytics) #116

Merged
chihlasm merged 66 commits from feat/flowpilot-ai-session into main 2026-03-21 05:15:51 +00:00
Showing only changes of commit 7518fe643b - Show all commits

View File

@@ -85,8 +85,21 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
exc_info=True exc_info=True
) )
# Re-raise exception to be handled by FastAPI # Return a proper response so it flows through CORSMiddleware.
raise # Re-raising from BaseHTTPMiddleware bypasses CORS headers.
from starlette.responses import JSONResponse
from fastapi import HTTPException
if isinstance(exc, HTTPException):
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
headers={"X-Correlation-ID": correlation_id, "X-Process-Time": f"{process_time:.3f}"},
)
return JSONResponse(
status_code=500,
content={"detail": "Internal server error"},
headers={"X-Correlation-ID": correlation_id, "X-Process-Time": f"{process_time:.3f}"},
)
class ErrorLoggingMiddleware(BaseHTTPMiddleware): class ErrorLoggingMiddleware(BaseHTTPMiddleware):
@@ -95,6 +108,11 @@ class ErrorLoggingMiddleware(BaseHTTPMiddleware):
Ensures all exceptions are logged before being returned to the client, Ensures all exceptions are logged before being returned to the client,
providing full stack traces for debugging. providing full stack traces for debugging.
IMPORTANT: Returns a JSONResponse instead of re-raising so the response
flows back through CORSMiddleware and gets proper CORS headers. Re-raising
exceptions from BaseHTTPMiddleware bypasses CORS, causing browsers to
report CORS errors instead of the actual error (e.g., 401).
""" """
async def dispatch( async def dispatch(
@@ -114,5 +132,17 @@ class ErrorLoggingMiddleware(BaseHTTPMiddleware):
exc_info=True exc_info=True
) )
# Re-raise to let FastAPI handle the response # Return a proper response so it flows through CORSMiddleware.
raise # If we re-raise, the response never passes through CORS and
# browsers see a CORS error instead of the actual error.
from starlette.responses import JSONResponse
from fastapi import HTTPException
if isinstance(exc, HTTPException):
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)
return JSONResponse(
status_code=500,
content={"detail": "Internal server error"},
)