fix(proxy): gate no-db rejection on db-unavailable flag and drop blind except

Signed-off-by: SIDDARTHA REDDY <75976672+SIDDARTHAREDDY8@users.noreply.github.com>
This commit is contained in:
SIDDARTHA REDDY 2026-10-17 13:04:32 -04:00
parent 6921e73e03
commit fef9c7e5bf
3 changed files with 21 additions and 10 deletions

View file

@ -2737,12 +2737,17 @@ async def user_api_key_auth_builder(
if (
prisma_client is None
): # if both master key + user key submitted, and user key != master key, and no db connected, raise an error
if not PrismaDBExceptionHandler.is_database_configured():
if (
not PrismaDBExceptionHandler.is_database_configured()
and PrismaDBExceptionHandler.should_allow_request_on_db_unavailable()
):
# No database was ever configured, so there is no outage to
# ride out. ``allow_requests_on_db_unavailable`` must not fail
# open here: a non-master key cannot be verified and is
# rejected, instead of being admitted via the
# ``no_db_connection`` fallback token. See #47119.
# ``no_db_connection`` fallback token. See #47119. When the
# flag is off no fallback token is issued anyway, so the
# established ``no_db_connection`` error below stands.
raise ProxyException(
message="Authentication Error - No database configured. Virtual keys require a configured database; only the master key can be used without one.",
type=ProxyErrorTypes.auth_error,

View file

@ -1,5 +1,6 @@
import os
import re
import sys
from collections.abc import Awaitable, Callable, Iterator
from http import HTTPStatus
from typing import Final, Protocol, TypeVar
@ -107,14 +108,13 @@ class PrismaDBExceptionHandler:
"""
if os.getenv("DATABASE_URL") or os.getenv("DIRECT_URL"):
return True
try:
from litellm.proxy.proxy_server import general_settings
if isinstance(general_settings, dict):
return bool(general_settings.get("database_url"))
except Exception:
return False
return False
# Read ``general_settings`` through ``sys.modules``: importing
# ``proxy_server`` here could fail or recurse while it is still
# being imported, and a proxy server that has not been imported
# yet has not configured a database through it either.
proxy_server_module = sys.modules.get("litellm.proxy.proxy_server")
general_settings = getattr(proxy_server_module, "general_settings", None)
return isinstance(general_settings, dict) and bool(general_settings.get("database_url"))
@staticmethod
def is_database_connection_error(e: Exception) -> bool:

View file

@ -964,3 +964,9 @@ def test_is_database_configured(monkeypatch):
monkeypatch.setenv("DATABASE_URL", "postgresql://user:pass@localhost:5432/litellm")
with patch("litellm.proxy.proxy_server.general_settings", {}):
assert PrismaDBExceptionHandler.is_database_configured() is True
monkeypatch.delenv("DATABASE_URL", raising=False)
with patch(
"litellm.proxy.proxy_server.general_settings",
{"database_url": "postgresql://localhost:5432/litellm"},
):
assert PrismaDBExceptionHandler.is_database_configured() is True