feat: improve error handling for Google Drive authentication

- Enhanced error handling in both Composio and Google Drive folder listing functions to check for expired authentication and mark connectors as 'auth_expired' when necessary.
- Added logging for failed persistence of authentication status and raised appropriate HTTP exceptions to prompt users for re-authentication.
- Streamlined the error checking process to include various authentication failure scenarios, improving overall robustness of the integration.
This commit is contained in:
Anish Sarkar 2026-03-20 14:48:31 +05:30
parent df0d9bb2b5
commit 510f9150cb
2 changed files with 47 additions and 3 deletions

View file

@ -686,6 +686,25 @@ async def list_composio_drive_folders(
items, error = await list_folder_contents(drive_client, parent_id=parent_id) items, error = await list_folder_contents(drive_client, parent_id=parent_id)
if error: if error:
error_lower = error.lower()
if (
"401" in error
or "invalid_grant" in error_lower
or "token has been expired or revoked" in error_lower
or "invalid credentials" in error_lower
or "authentication failed" in error_lower
):
try:
if connector and not connector.config.get("auth_expired"):
connector.config = {**connector.config, "auth_expired": True}
flag_modified(connector, "config")
await session.commit()
logger.info(f"Marked Composio connector {connector_id} as auth_expired")
except Exception:
logger.warning(f"Failed to persist auth_expired for connector {connector_id}", exc_info=True)
raise HTTPException(
status_code=400, detail="Google Drive authentication expired. Please re-authenticate."
)
raise HTTPException( raise HTTPException(
status_code=500, detail=f"Failed to list folder contents: {error}" status_code=500, detail=f"Failed to list folder contents: {error}"
) )

View file

@ -503,11 +503,31 @@ async def list_google_drive_folders(
items, error = await list_folder_contents(drive_client, parent_id=parent_id) items, error = await list_folder_contents(drive_client, parent_id=parent_id)
if error: if error:
error_lower = error.lower()
if (
"401" in error
or "invalid_grant" in error_lower
or "token has been expired or revoked" in error_lower
or "invalid credentials" in error_lower
or "authentication failed" in error_lower
):
from sqlalchemy.orm.attributes import flag_modified
try:
if connector and not connector.config.get("auth_expired"):
connector.config = {**connector.config, "auth_expired": True}
flag_modified(connector, "config")
await session.commit()
logger.info(f"Marked connector {connector_id} as auth_expired")
except Exception:
logger.warning(f"Failed to persist auth_expired for connector {connector_id}", exc_info=True)
raise HTTPException(
status_code=400, detail="Google Drive authentication expired. Please re-authenticate."
)
raise HTTPException( raise HTTPException(
status_code=500, detail=f"Failed to list folder contents: {error}" status_code=500, detail=f"Failed to list folder contents: {error}"
) )
# Count folders and files for better logging
folder_count = sum(1 for item in items if item.get("isFolder", False)) folder_count = sum(1 for item in items if item.get("isFolder", False))
file_count = len(items) - folder_count file_count = len(items) - folder_count
@ -516,7 +536,6 @@ async def list_google_drive_folders(
+ (f" in folder {parent_id}" if parent_id else " in ROOT") + (f" in folder {parent_id}" if parent_id else " in ROOT")
) )
# Log first few items for debugging
if items: if items:
logger.info(f"First 3 items: {[item.get('name') for item in items[:3]]}") logger.info(f"First 3 items: {[item.get('name') for item in items[:3]]}")
@ -527,7 +546,13 @@ async def list_google_drive_folders(
except Exception as e: except Exception as e:
logger.error(f"Error listing Drive contents: {e!s}", exc_info=True) logger.error(f"Error listing Drive contents: {e!s}", exc_info=True)
error_lower = str(e).lower() error_lower = str(e).lower()
if "invalid_grant" in error_lower or "token has been expired or revoked" in error_lower or "authentication failed" in error_lower: if (
"401" in str(e)
or "invalid_grant" in error_lower
or "token has been expired or revoked" in error_lower
or "invalid credentials" in error_lower
or "authentication failed" in error_lower
):
from sqlalchemy.orm.attributes import flag_modified from sqlalchemy.orm.attributes import flag_modified
try: try: