mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
fix(mcp): surface DB-unavailable as a real error on per-user env var lookup
When prisma_client is None, _load_user_env_vars returned an empty dict, which on the tool-call path was indistinguishable from "user has no stored values" and produced a misleading 412 directing the user to set up credentials they can never store without a database. Raise instead so the tool-call path fails with a clear error and the listing path stays best-effort via its existing catch.
This commit is contained in:
parent
63a9f00103
commit
3ac1c00aa0
2 changed files with 42 additions and 7 deletions
|
|
@ -1697,9 +1697,11 @@ class MCPServerManager:
|
|||
window; the cache is invalidated when the user stores or clears values.
|
||||
Pass ``force_refresh`` to bypass the cache read and re-fetch from the DB
|
||||
(used before raising a "missing credentials" error so a process-local
|
||||
stale entry cannot mask values stored on another worker). DB errors
|
||||
propagate so the caller can decide between failing the request (tool-call
|
||||
path) and staying best-effort (listing path).
|
||||
stale entry cannot mask values stored on another worker). A missing DB
|
||||
connection and any other DB error propagate so the caller can decide
|
||||
between failing the request (tool-call path) and staying best-effort
|
||||
(listing path); they must never be mistaken for "user has no values",
|
||||
which would send the user a misleading "set up your credentials" 412.
|
||||
"""
|
||||
if user_api_key_auth is None:
|
||||
return {}
|
||||
|
|
@ -1718,7 +1720,11 @@ class MCPServerManager:
|
|||
from litellm.proxy.proxy_server import prisma_client # noqa: PLC0415
|
||||
|
||||
if prisma_client is None:
|
||||
return {}
|
||||
raise RuntimeError(
|
||||
"MCP per-user env vars require a database connection, but none "
|
||||
"is configured. Connect a database to your proxy to use per-user "
|
||||
"MCP env vars."
|
||||
)
|
||||
from litellm.proxy._experimental.mcp_server.db import ( # noqa: PLC0415
|
||||
get_user_env_vars,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -484,8 +484,11 @@ async def test_load_user_env_vars_returns_empty_without_user_id():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_load_user_env_vars_returns_empty_when_db_unavailable(monkeypatch):
|
||||
"""If prisma_client is None, the lookup short-circuits rather than crashing."""
|
||||
async def test_load_user_env_vars_raises_when_db_unavailable(monkeypatch):
|
||||
"""A missing DB connection must raise, not return ``{}``. Returning ``{}``
|
||||
would be indistinguishable from "user has no values" and would mislead the
|
||||
tool-call path into a "set up your credentials" 412 the user can never
|
||||
satisfy (per-user env vars are unusable without a DB)."""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from litellm.proxy._experimental.mcp_server.mcp_server_manager import (
|
||||
|
|
@ -500,7 +503,33 @@ async def test_load_user_env_vars_returns_empty_when_db_unavailable(monkeypatch)
|
|||
fake_auth = MagicMock()
|
||||
fake_auth.user_id = "alice"
|
||||
monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", None)
|
||||
assert await manager._load_user_env_vars(server, fake_auth) == {}
|
||||
with pytest.raises(RuntimeError, match="database connection"):
|
||||
await manager._load_user_env_vars(server, fake_auth)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_static_headers_db_unavailable_is_not_missing_412(
|
||||
mock_server, monkeypatch
|
||||
):
|
||||
"""On the tool-call path, an unavailable DB must surface as a real error
|
||||
rather than a misleading MCPMissingUserEnvVarsError (412). This guards the
|
||||
regression where ``_load_user_env_vars`` returned ``{}`` when prisma_client
|
||||
was None, making a DB outage look like "user has no credentials"."""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from litellm.proxy._experimental.mcp_server.mcp_server_manager import (
|
||||
MCPServerManager,
|
||||
)
|
||||
|
||||
manager = MCPServerManager()
|
||||
fake_auth = MagicMock()
|
||||
fake_auth.user_id = "alice"
|
||||
monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", None)
|
||||
|
||||
with pytest.raises(RuntimeError, match="database connection"):
|
||||
await manager._resolve_static_headers_with_env_vars(
|
||||
mock_server, user_api_key_auth=fake_auth
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue