fix(backend/mcp): Fix test_routes.py tests and refine exception handling

- discover_tools: Keep generic Exception catch → 502 for MCP connectivity errors
- mcp_oauth_callback: Add targeted exception handler for token exchange → 400
- test_routes: Fix discover_auth_server_metadata mock for no-OAuth-support case
- oauth.py: Auto-formatting only
This commit is contained in:
Zamil Majdy
2026-02-10 22:22:38 +04:00
parent fbe4c740cb
commit 4ac025da09
3 changed files with 17 additions and 9 deletions

View File

@@ -120,6 +120,11 @@ async def discover_tools(
raise fastapi.HTTPException(status_code=502, detail=str(e))
except MCPClientError as e:
raise fastapi.HTTPException(status_code=502, detail=str(e))
except Exception as e:
raise fastapi.HTTPException(
status_code=502,
detail=f"Failed to connect to MCP server: {e}",
)
return DiscoverToolsResponse(
tools=[
@@ -316,9 +321,15 @@ async def mcp_oauth_callback(
resource_url=meta.get("resource_url"),
)
credentials = await handler.exchange_code_for_tokens(
request.code, valid_state.scopes, valid_state.code_verifier
)
try:
credentials = await handler.exchange_code_for_tokens(
request.code, valid_state.scopes, valid_state.code_verifier
)
except Exception as e:
raise fastapi.HTTPException(
status_code=400,
detail=f"OAuth token exchange failed: {e}",
)
# Enrich credential metadata for future lookup and token refresh
if credentials.metadata is None:

View File

@@ -239,6 +239,7 @@ class TestOAuthLogin:
with patch("backend.api.features.mcp.routes.MCPClient") as MockClient:
instance = MockClient.return_value
instance.discover_auth = AsyncMock(return_value=None)
instance.discover_auth_server_metadata = AsyncMock(return_value=None)
response = client.post(
"/oauth/login",

View File

@@ -110,9 +110,7 @@ class MCPOAuthHandler(BaseOAuthHandler):
)
if "access_token" not in tokens:
raise RuntimeError(
"OAuth token response missing 'access_token' field"
)
raise RuntimeError("OAuth token response missing 'access_token' field")
now = int(time.time())
expires_in = tokens.get("expires_in")
@@ -164,9 +162,7 @@ class MCPOAuthHandler(BaseOAuthHandler):
)
if "access_token" not in tokens:
raise RuntimeError(
"OAuth refresh response missing 'access_token' field"
)
raise RuntimeError("OAuth refresh response missing 'access_token' field")
now = int(time.time())
expires_in = tokens.get("expires_in")