fix(agent): improve error handling for get_agent_soul method

This commit is contained in:
Abhimanyu Saharan
2026-03-03 03:09:29 +05:30
parent 0fe61e3e08
commit 77870b0fc7
3 changed files with 36 additions and 20 deletions

View File

@@ -1429,11 +1429,25 @@ async def get_agent_soul(
target_agent_id=agent_id,
)
coordination = GatewayCoordinationService(session)
return await coordination.get_agent_soul(
board=board,
target_agent_id=agent_id,
correlation_id=f"soul.read:{board.id}:{agent_id}",
)
try:
return await coordination.get_agent_soul(
board=board,
target_agent_id=agent_id,
correlation_id=f"soul.read:{board.id}:{agent_id}",
)
except HTTPException as exc:
# Keep explicit auth/not-found responses, but avoid relaying internal 5xx details.
if exc.status_code >= status.HTTP_500_INTERNAL_SERVER_ERROR:
raise HTTPException(
status_code=exc.status_code,
detail="Gateway SOUL read failed",
) from exc
raise
except Exception as exc: # pragma: no cover - defensive API boundary guard
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail="Gateway SOUL read failed",
) from exc
@router.put(

View File

@@ -237,7 +237,6 @@ async def _authenticate_clerk_request(request: Request) -> RequestState:
async def _fetch_clerk_profile(clerk_user_id: str) -> tuple[str | None, str | None]:
secret = settings.clerk_secret_key.strip()
secret_kind = secret.split("_", maxsplit=1)[0] if "_" in secret else "unknown"
server_url = _normalize_clerk_server_url(settings.clerk_api_url or "")
clerk_user_id_log = clerk_user_id[-6:] if clerk_user_id else ""
@@ -252,28 +251,24 @@ async def _fetch_clerk_profile(clerk_user_id: str) -> tuple[str | None, str | No
return email, name
except ClerkErrors as exc:
logger.warning(
"auth.clerk.profile.fetch_failed clerk_user_id=%s reason=clerk_errors "
"secret_kind=%s error_type=%s",
"auth.clerk.profile.fetch_failed clerk_user_id=%s reason=clerk_errors " "error_type=%s",
clerk_user_id_log,
secret_kind,
exc.__class__.__name__,
)
except SDKError as exc:
logger.warning(
"auth.clerk.profile.fetch_failed clerk_user_id=%s status=%s reason=sdk_error "
"server_url=%s secret_kind=%s",
"server_url=%s",
clerk_user_id_log,
exc.status_code,
server_url,
secret_kind,
)
except httpx.TimeoutException as exc:
logger.warning(
"auth.clerk.profile.fetch_failed clerk_user_id=%s reason=timeout "
"server_url=%s secret_kind=%s error=%s",
"server_url=%s error=%s",
clerk_user_id_log,
server_url,
secret_kind,
str(exc) or exc.__class__.__name__,
)
except Exception as exc:
@@ -293,7 +288,6 @@ async def delete_clerk_user(clerk_user_id: str) -> None:
return
secret = settings.clerk_secret_key.strip()
secret_kind = secret.split("_", maxsplit=1)[0] if "_" in secret else "unknown"
server_url = _normalize_clerk_server_url(settings.clerk_api_url or "")
clerk_user_id_log = clerk_user_id[-6:] if clerk_user_id else ""
@@ -307,10 +301,8 @@ async def delete_clerk_user(clerk_user_id: str) -> None:
logger.info("auth.clerk.user.delete clerk_user_id=%s", clerk_user_id_log)
except ClerkErrors as exc:
logger.warning(
"auth.clerk.user.delete_failed clerk_user_id=%s reason=clerk_errors "
"secret_kind=%s error_type=%s",
"auth.clerk.user.delete_failed clerk_user_id=%s reason=clerk_errors " "error_type=%s",
clerk_user_id_log,
secret_kind,
exc.__class__.__name__,
)
raise HTTPException(
@@ -323,11 +315,10 @@ async def delete_clerk_user(clerk_user_id: str) -> None:
return
logger.warning(
"auth.clerk.user.delete_failed clerk_user_id=%s status=%s reason=sdk_error "
"server_url=%s secret_kind=%s",
"server_url=%s",
clerk_user_id_log,
exc.status_code,
server_url,
secret_kind,
)
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,

View File

@@ -4,6 +4,7 @@ from __future__ import annotations
import re
from datetime import date, datetime
from functools import lru_cache
from typing import Literal, Self
from urllib.parse import urlparse
from uuid import UUID
@@ -297,6 +298,12 @@ def _parse_iso_datetime(value: str) -> datetime:
return datetime.fromisoformat(normalized)
@lru_cache(maxsize=256)
def _compiled_validation_regex(pattern: str) -> re.Pattern[str]:
"""Compile and cache validation regex patterns for value checks."""
return re.compile(pattern)
def validate_custom_field_value(
*,
field_type: TaskCustomFieldType,
@@ -346,7 +353,11 @@ def validate_custom_field_value(
if validation_regex is not None and field_type in STRING_FIELD_TYPES:
if not isinstance(value, str):
raise ValueError("must be a string for regex validation")
if re.fullmatch(validation_regex, value) is None:
try:
pattern = _compiled_validation_regex(validation_regex)
except re.error as exc:
raise ValueError(f"validation_regex is invalid: {exc}") from exc
if pattern.fullmatch(value) is None:
raise ValueError("does not match validation_regex")