From be2e30f118c7008d290744eec13e7b28eaac6e5f Mon Sep 17 00:00:00 2001 From: Maryam Fareed Date: Sat, 12 Sep 2026 22:12:08 +0500 Subject: [PATCH 1/4] Improve ingestion error logging --- web/backend/main.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/web/backend/main.py b/web/backend/main.py index 1ca1072..fb994fb 100644 --- a/web/backend/main.py +++ b/web/backend/main.py @@ -98,13 +98,13 @@ async def process_file_ingestion(file_id: Any, document_id: str, filename: str, with open(file_path, "rb") as f: file_bytes = f.read() - async with httpx.AsyncClient(timeout=15) as client: - internal_token = create_access_token(email=user_id) - response = await client.post( - f"{INGESTION_SERVICE_URL.rstrip('/')}/ingest/pdf", - files={"file": (filename, file_bytes, "application/pdf")}, - headers={"Authorization": f"Bearer {internal_token}"}, - ) + async with httpx.AsyncClient(timeout=120) as client: + internal_token = create_access_token(email=user_id) + response = await client.post( + f"{INGESTION_SERVICE_URL.rstrip('/')}/ingest/pdf", + files={"file": (filename, file_bytes, "application/pdf")}, + headers={"Authorization": f"Bearer {internal_token}"}, + ) if response.status_code == 200: try: @@ -124,11 +124,11 @@ async def process_file_ingestion(file_id: Any, document_id: str, filename: str, ) except Exception as e: - logger.warning( - f"Ingestion error for {filename} ({document_id}): {e}" + logger.exception( + f"Ingestion error for {filename} ({document_id})" ) new_status = "Failed" - last_error = str(e) + last_error = f"{type(e).__name__}: {str(e)}" else: new_status = "Failed" last_error = "File not found on disk" From dd1070bb3d6a1e8c59e3d88191c757ee1d4ec5d9 Mon Sep 17 00:00:00 2001 From: Maryam Fareed Date: Sat, 12 Sep 2026 22:19:28 +0500 Subject: [PATCH 2/4] Expose ingestion exception details --- web/backend/main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/backend/main.py b/web/backend/main.py index fb994fb..10f1de2 100644 --- a/web/backend/main.py +++ b/web/backend/main.py @@ -124,11 +124,11 @@ async def process_file_ingestion(file_id: Any, document_id: str, filename: str, ) except Exception as e: - logger.exception( - f"Ingestion error for {filename} ({document_id})" - ) + error_details = f"{type(e).__name__}: {repr(e)}" + print(f"INGESTION_EXCEPTION: {error_details}", flush=True) + logger.error(f"INGESTION_EXCEPTION: {error_details}", flush=True) new_status = "Failed" - last_error = f"{type(e).__name__}: {str(e)}" + last_error = error_details else: new_status = "Failed" last_error = "File not found on disk" From 400a30184532a4856a0a468b05d3ec8421377d2f Mon Sep 17 00:00:00 2001 From: Maryam Fareed Date: Sun, 13 Sep 2026 15:09:15 +0500 Subject: [PATCH 3/4] Normalize user email casing/whitespace when resolving user_id --- web/backend/main.py | 14 +++++++------- web/backend/routes/__init__.py | 0 web/backend/routes/chat.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 web/backend/routes/__init__.py diff --git a/web/backend/main.py b/web/backend/main.py index 10f1de2..3beea08 100644 --- a/web/backend/main.py +++ b/web/backend/main.py @@ -11,7 +11,7 @@ from pypdf import PdfReader import httpx -from models import ( +from web.backend.models import ( SignupRequest, LoginRequest, Upload, @@ -20,23 +20,23 @@ QuizResult, QuizResultRequest, ) -from database import ( +from web.backend.database import ( get_users_collection, get_uploads_collection, get_chat_history_collection, get_quiz_results_collection, ) -from auth_utils import ( +from web.backend.auth_utils import ( hash_password, verify_password, create_access_token, get_current_user_email, verify_internal_service_key, ) -from routes.chat import router as chat_router -from routes.oauth import router as oauth_router -from routes.quiz import router as quiz_router -from routes.flashcards import router as flashcards_router +from web.backend.routes.chat import router as chat_router +from web.backend.routes.oauth import router as oauth_router +from web.backend.routes.quiz import router as quiz_router +from web.backend.routes.flashcards import router as flashcards_router logger = logging.getLogger("uvicorn") diff --git a/web/backend/routes/__init__.py b/web/backend/routes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/backend/routes/chat.py b/web/backend/routes/chat.py index acf385f..65b9ffa 100644 --- a/web/backend/routes/chat.py +++ b/web/backend/routes/chat.py @@ -44,7 +44,7 @@ async def ask( current_user_email: str = Depends(get_current_user_email), ): # Strictly derive user_id from the authenticated JWT session (email) only. - resolved_user_id = current_user_email + resolved_user_id = current_user_email.strip().lower() # Helper to check if user is asking for a general summary/overview q_lower = request.question.lower().strip() @@ -157,4 +157,4 @@ async def ask( "Chatbot service is currently unavailable. " "Please make sure it's running and try again." ), - ) \ No newline at end of file + ) From d0f249c036a636854a5957a0639873183ca58fc4 Mon Sep 17 00:00:00 2001 From: Maryam Fareed Date: Sun, 13 Sep 2026 15:16:53 +0500 Subject: [PATCH 4/4] Resolve merge conflict: keep web.backend import paths and roadmap router --- web/backend/main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/backend/main.py b/web/backend/main.py index 3beea08..1598fb3 100644 --- a/web/backend/main.py +++ b/web/backend/main.py @@ -37,6 +37,9 @@ from web.backend.routes.oauth import router as oauth_router from web.backend.routes.quiz import router as quiz_router from web.backend.routes.flashcards import router as flashcards_router +from web.backend.routes.roadmap import router as roadmap_router + + logger = logging.getLogger("uvicorn") @@ -67,6 +70,7 @@ app.include_router(oauth_router) app.include_router(quiz_router) app.include_router(flashcards_router) +app.include_router(roadmap_router) UPLOAD_DIRECTORY = os.getenv(