From 249b6e9ad18194893db50e7e32d2538ae32d0f1c Mon Sep 17 00:00:00 2001 From: Aditya30ag Date: Mon, 27 Oct 2025 19:20:13 +0530 Subject: [PATCH 1/3] fix: bug fixes in backend and frontend integration --- backend/app/core/orchestration/queue_manager.py | 2 +- backend/app/database/weaviate/client.py | 4 ++-- frontend/src/App.tsx | 2 -- frontend/src/components/integration/BotIntegration.tsx | 6 ++++-- frontend/src/lib/api.ts | 5 ++--- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/backend/app/core/orchestration/queue_manager.py b/backend/app/core/orchestration/queue_manager.py index 346bc9a0..b2b033f3 100644 --- a/backend/app/core/orchestration/queue_manager.py +++ b/backend/app/core/orchestration/queue_manager.py @@ -41,7 +41,7 @@ async def connect(self): await self.channel.declare_queue(queue_name, durable=True) logger.info("Successfully connected to RabbitMQ") except Exception as e: - logger.error(f"Failed to connect to RabbitMQ: {e}") + logger.error(f"Failed to connect to RabbitMQ: {e}", exc_info=True) raise async def start(self, num_workers: int = 3): diff --git a/backend/app/database/weaviate/client.py b/backend/app/database/weaviate/client.py index 5ed11ede..b14ff4e4 100644 --- a/backend/app/database/weaviate/client.py +++ b/backend/app/database/weaviate/client.py @@ -23,10 +23,10 @@ async def get_weaviate_client() -> AsyncGenerator[weaviate.WeaviateClient, None] await client.connect() yield client except Exception as e: - logger.error(f"Weaviate client error: {str(e)}") + logger.error(f"Weaviate client error: {str(e)}", exc_info=True) raise finally: try: await client.close() except Exception as e: - logger.warning(f"Error closing Weaviate client: {str(e)}") + logger.warning(f"Error closing Weaviate client: {str(e)}", exc_info=True) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9f70aa6c..f506220c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -47,7 +47,6 @@ function App() { supabase.auth.getSession().then(({ data, error }) => { if (error) { toast.error('User Login Failed'); - console.error('Error checking session:', error); return; } setIsAuthenticated(!!data.session); @@ -93,7 +92,6 @@ function App() { const { error } = await supabase.auth.signOut(); if (error) { toast.error('Logout failed'); - console.error('Error during logout:', error); return; } toast.success('Signed out!'); diff --git a/frontend/src/components/integration/BotIntegration.tsx b/frontend/src/components/integration/BotIntegration.tsx index 813c251c..283e37f3 100644 --- a/frontend/src/components/integration/BotIntegration.tsx +++ b/frontend/src/components/integration/BotIntegration.tsx @@ -46,8 +46,10 @@ const BotIntegration: React.FC = ({ } else { setIntegration(null); } - } catch (error) { - console.error('Error loading integration status:', error); + } catch { + // Silently handle integration status loading errors + setIsConnected(false); + setIntegration(null); } }; diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 963ca3bc..e9ba9c86 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -86,7 +86,7 @@ class ApiClient { (error) => { if (error.response?.status === 401) { // Handle unauthorized - could redirect to login - console.error('Unauthorized request'); + // Silently handle unauthorized requests } return Promise.reject(error); } @@ -165,8 +165,7 @@ class ApiClient { try { const response = await this.client.get('/v1/health'); return response.status === 200; - } catch (error) { - console.error('Backend health check failed:', error); + } catch { return false; } } From 73a7e87c2ef15bea9ed9a88dc02f37e77f3a7124 Mon Sep 17 00:00:00 2001 From: Aditya30ag Date: Wed, 29 Oct 2025 01:41:02 +0530 Subject: [PATCH 2/3] fix code rabbit suggestion --- backend/app/core/orchestration/queue_manager.py | 16 ++++++++++++---- backend/app/database/weaviate/client.py | 17 ++++++----------- .../components/integration/BotIntegration.tsx | 8 ++++++-- frontend/src/lib/api.ts | 17 +++++++++++++---- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/backend/app/core/orchestration/queue_manager.py b/backend/app/core/orchestration/queue_manager.py index b2b033f3..885424be 100644 --- a/backend/app/core/orchestration/queue_manager.py +++ b/backend/app/core/orchestration/queue_manager.py @@ -79,14 +79,22 @@ async def enqueue(self, if delay > 0: await asyncio.sleep(delay) + # Guard against publishing while disconnected + if not self.channel or self.channel.is_closed: + raise RuntimeError("Queue channel is not connected. Call start() before enqueue().") + queue_item = { "id": message.get("id", f"msg_{datetime.now().timestamp()}"), - "priority": priority, + "priority": priority.value, # Serialize enum to string "data": message } json_message = json.dumps(queue_item).encode() await self.channel.default_exchange.publish( - aio_pika.Message(body=json_message), + aio_pika.Message( + body=json_message, + delivery_mode=aio_pika.DeliveryMode.PERSISTENT, + content_type="application/json" + ), routing_key=self.queues[priority] ) logger.info(f"Enqueued message {queue_item['id']} with priority {priority}") @@ -114,13 +122,13 @@ async def _worker(self, worker_name: str): await self._process_item(item, worker_name) await message.ack() except Exception as e: - logger.error(f"Error processing message: {e}") + logger.error("Error processing message: %s", e, exc_info=True) await message.nack(requeue=False) except asyncio.CancelledError: logger.info(f"Worker {worker_name} cancelled") return except Exception as e: - logger.error(f"Worker {worker_name} error: {e}") + logger.error("Worker %s error: %s", worker_name, e, exc_info=True) await asyncio.sleep(0.1) async def _process_item(self, item: Dict[str, Any], worker_name: str): diff --git a/backend/app/database/weaviate/client.py b/backend/app/database/weaviate/client.py index b14ff4e4..51325962 100644 --- a/backend/app/database/weaviate/client.py +++ b/backend/app/database/weaviate/client.py @@ -1,19 +1,14 @@ import weaviate +import weaviate.exceptions from contextlib import asynccontextmanager from typing import AsyncGenerator import logging logger = logging.getLogger(__name__) -_client = None - - def get_client(): - """Get or create the global Weaviate client instance.""" - global _client - if _client is None: - _client = weaviate.use_async_with_local() - return _client + """Create a new async Weaviate client instance per context use.""" + return weaviate.use_async_with_local() @asynccontextmanager async def get_weaviate_client() -> AsyncGenerator[weaviate.WeaviateClient, None]: @@ -22,11 +17,11 @@ async def get_weaviate_client() -> AsyncGenerator[weaviate.WeaviateClient, None] try: await client.connect() yield client - except Exception as e: - logger.error(f"Weaviate client error: {str(e)}", exc_info=True) + except weaviate.exceptions.WeaviateBaseError as e: + logger.error("Weaviate client error: %s", e, exc_info=True) raise finally: try: await client.close() except Exception as e: - logger.warning(f"Error closing Weaviate client: {str(e)}", exc_info=True) + logger.warning("Error closing Weaviate client: %s", e, exc_info=True) diff --git a/frontend/src/components/integration/BotIntegration.tsx b/frontend/src/components/integration/BotIntegration.tsx index 283e37f3..99dcf2ae 100644 --- a/frontend/src/components/integration/BotIntegration.tsx +++ b/frontend/src/components/integration/BotIntegration.tsx @@ -46,10 +46,14 @@ const BotIntegration: React.FC = ({ } else { setIntegration(null); } - } catch { - // Silently handle integration status loading errors + } catch (error) { + // Handle integration status loading errors setIsConnected(false); setIntegration(null); + // Log in development for debugging + if (import.meta.env.DEV) { + console.error('Failed to load integration status:', error); + } } }; diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index e9ba9c86..553c1bf6 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -83,10 +83,15 @@ class ApiClient { // Add response interceptor for error handling this.client.interceptors.response.use( (response) => response, - (error) => { + async (error) => { if (error.response?.status === 401) { - // Handle unauthorized - could redirect to login - // Silently handle unauthorized requests + // Clear session and redirect to login + // Avoid infinite redirect loop if already on login page + if (!window.location.pathname.includes('/login')) { + await supabase.auth.signOut(); + const returnUrl = encodeURIComponent(window.location.pathname + window.location.search); + window.location.href = `/login?returnUrl=${returnUrl}`; + } } return Promise.reject(error); } @@ -165,7 +170,11 @@ class ApiClient { try { const response = await this.client.get('/v1/health'); return response.status === 200; - } catch { + } catch (error) { + // Log in development for debugging + if (import.meta.env.DEV) { + console.error('Health check failed:', error); + } return false; } } From c04454109146ea556fd873fe00c3240cab2298ac Mon Sep 17 00:00:00 2001 From: Aditya30ag Date: Sun, 28 Dec 2025 10:13:06 +0530 Subject: [PATCH 3/3] fixes the requested issues --- frontend/src/components/pages/LoginPage.tsx | 19 ++++++++-- frontend/src/lib/api.ts | 41 ++++++++++++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/pages/LoginPage.tsx b/frontend/src/components/pages/LoginPage.tsx index 5a91c2d3..6d83ae12 100644 --- a/frontend/src/components/pages/LoginPage.tsx +++ b/frontend/src/components/pages/LoginPage.tsx @@ -1,6 +1,6 @@ import { useState, ReactNode, FormEvent } from "react"; import { motion } from "framer-motion"; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useSearchParams } from 'react-router-dom'; import { toast } from "react-hot-toast"; import { supabase } from "../../lib/supabaseClient"; import { @@ -49,6 +49,7 @@ const InputField = ({ icon: Icon, ...props }: InputFieldProps) => ( export default function LoginPage({ onLogin }: LoginPageProps) { const navigate = useNavigate(); + const [searchParams] = useSearchParams(); const [isLoading, setIsLoading] = useState(false); const handleLogin = async (e: FormEvent) => { @@ -64,8 +65,20 @@ export default function LoginPage({ onLogin }: LoginPageProps) { setIsLoading(false); if(data && !error){ toast.success('Successfully logged in!'); - onLogin(); - navigate('/'); + onLogin(); + const rawReturn = searchParams.get('returnUrl'); + try { + const decoded = rawReturn ? decodeURIComponent(rawReturn) : null; + // Protect against open redirects by only allowing internal paths + if (decoded && decoded.startsWith('/')) { + navigate(decoded, { replace: true }); + } else { + navigate('/', { replace: true }); + } + } catch (e) { + // If decoding fails, fallback to home + navigate('/', { replace: true }); + } } else { diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 553c1bf6..33fc682a 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -4,6 +4,18 @@ import axios, { AxiosInstance } from 'axios'; import { supabase } from './supabaseClient'; +// Prevents multiple simultaneous 401 handlers from racing and triggering +// sign-out/redirect more than once. +let isHandlingUnauthorized = false; + +// Public routes where we should NOT force a redirect to login +const PUBLIC_PATHS = [ + '/login', + '/signup', + '/forgot-password', + '/reset-password', +]; + // Backend API base URL const API_BASE_URL = import.meta.env.VITE_BACKEND_URL || 'http://localhost:8000'; @@ -85,11 +97,30 @@ class ApiClient { (response) => response, async (error) => { if (error.response?.status === 401) { - // Clear session and redirect to login - // Avoid infinite redirect loop if already on login page - if (!window.location.pathname.includes('/login')) { - await supabase.auth.signOut(); - const returnUrl = encodeURIComponent(window.location.pathname + window.location.search); + const pathname = window.location.pathname || '/'; + + // If we're already on a public/auth page (login, signup, reset, etc.) + // don't yank the user away mid-flow. + if (PUBLIC_PATHS.some((p) => pathname.startsWith(p))) { + return Promise.reject(error); + } + + // Deduplicate concurrent 401 handlers to avoid multiple sign-outs / redirects + if (!isHandlingUnauthorized) { + isHandlingUnauthorized = true; + try { + await supabase.auth.signOut(); + } catch (e) { + // Log but continue to redirect; signing out isn't critical here + console.error( + 'Error signing out on 401 handler', + e + ); + } + + const returnUrl = encodeURIComponent( + pathname + window.location.search + ); window.location.href = `/login?returnUrl=${returnUrl}`; } }