mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
fix(auth): lower invalid virtual key log severity
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2b10dc5a7a
commit
ba2135e266
2 changed files with 64 additions and 9 deletions
|
|
@ -110,10 +110,19 @@ class UserAPIKeyAuthExceptionHandler:
|
|||
request=request,
|
||||
use_x_forwarded_for=general_settings.get("use_x_forwarded_for") is True,
|
||||
)
|
||||
is_invalid_virtual_key: Final = (
|
||||
isinstance(e, HTTPException)
|
||||
and e.status_code == status.HTTP_401_UNAUTHORIZED
|
||||
and "LiteLLM Virtual Key expected" in str(e.detail)
|
||||
)
|
||||
log_fn: Final = (
|
||||
verbose_proxy_logger.error
|
||||
if is_expected_client_error(e) and not litellm.log_client_error_tracebacks
|
||||
else verbose_proxy_logger.exception
|
||||
verbose_proxy_logger.info
|
||||
if is_invalid_virtual_key and not litellm.log_client_error_tracebacks
|
||||
else (
|
||||
verbose_proxy_logger.error
|
||||
if is_expected_client_error(e) and not litellm.log_client_error_tracebacks
|
||||
else verbose_proxy_logger.exception
|
||||
)
|
||||
)
|
||||
log_fn(
|
||||
"litellm.proxy.proxy_server.user_api_key_auth(): Exception occured - %s\nRequester IP Address:%s",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import httpx
|
||||
|
|
@ -705,19 +706,59 @@ async def test_auth_failure_ip_stamp_does_not_mutate_callers_request_data():
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"auth_error,expect_traceback",
|
||||
"auth_error,expected_level,expect_traceback,log_client_error_tracebacks",
|
||||
[
|
||||
pytest.param(
|
||||
HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="LiteLLM Virtual Key expected. Received=unde****ined, expected to start with 'sk-'.",
|
||||
),
|
||||
logging.INFO,
|
||||
False,
|
||||
False,
|
||||
id="invalid_virtual_key_logs_at_info_without_traceback",
|
||||
),
|
||||
pytest.param(
|
||||
HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="LiteLLM Virtual Key expected. Received=unde****ined, expected to start with 'sk-'.",
|
||||
),
|
||||
logging.ERROR,
|
||||
True,
|
||||
True,
|
||||
id="invalid_virtual_key_keeps_traceback_opt_in",
|
||||
),
|
||||
pytest.param(
|
||||
ProxyException(
|
||||
message="Authentication Error", type=ProxyErrorTypes.auth_error, param=None, code=401
|
||||
),
|
||||
logging.ERROR,
|
||||
False,
|
||||
id="expected_401_no_traceback",
|
||||
False,
|
||||
id="other_expected_401_keeps_error_level_without_traceback",
|
||||
),
|
||||
pytest.param(
|
||||
ValueError("unexpected internal error"),
|
||||
logging.ERROR,
|
||||
True,
|
||||
False,
|
||||
id="unexpected_error_keeps_traceback",
|
||||
),
|
||||
pytest.param(
|
||||
HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Authentication database unavailable",
|
||||
),
|
||||
logging.ERROR,
|
||||
True,
|
||||
False,
|
||||
id="server_error_keeps_traceback",
|
||||
),
|
||||
pytest.param(ValueError("unexpected internal error"), True, id="unexpected_error_keeps_traceback"),
|
||||
],
|
||||
)
|
||||
async def test_handle_authentication_error_traceback_only_for_unexpected_errors(auth_error, expect_traceback, caplog):
|
||||
async def test_handle_authentication_error_traceback_only_for_unexpected_errors(
|
||||
auth_error, expected_level, expect_traceback, log_client_error_tracebacks, caplog
|
||||
):
|
||||
"""Regression for LIT-6043: expected 4xx auth rejections must not format a
|
||||
traceback via logger.exception; unexpected errors must keep it."""
|
||||
handler = UserAPIKeyAuthExceptionHandler()
|
||||
|
|
@ -731,6 +772,10 @@ async def test_handle_authentication_error_traceback_only_for_unexpected_errors(
|
|||
patch( # test-quality-ok: handler reads proxy_server globals at call time
|
||||
"litellm.proxy.auth.auth_exception_handler.seed_request_identity",
|
||||
),
|
||||
patch(
|
||||
"litellm.proxy.auth.auth_exception_handler.litellm.log_client_error_tracebacks",
|
||||
log_client_error_tracebacks,
|
||||
),
|
||||
patch( # test-quality-ok: handler reads proxy_server globals at call time
|
||||
"litellm.proxy.proxy_server.general_settings",
|
||||
{"allow_requests_on_db_unavailable": False},
|
||||
|
|
@ -740,8 +785,8 @@ async def test_handle_authentication_error_traceback_only_for_unexpected_errors(
|
|||
try:
|
||||
try:
|
||||
raise auth_error
|
||||
except (ProxyException, ValueError) as caught:
|
||||
with caplog.at_level("ERROR", logger="LiteLLM Proxy"), pytest.raises(ProxyException):
|
||||
except (HTTPException, ProxyException, ValueError) as caught:
|
||||
with caplog.at_level(logging.DEBUG, logger="LiteLLM Proxy"), pytest.raises(ProxyException):
|
||||
await handler._handle_authentication_error(
|
||||
caught,
|
||||
MagicMock(),
|
||||
|
|
@ -755,4 +800,5 @@ async def test_handle_authentication_error_traceback_only_for_unexpected_errors(
|
|||
|
||||
records = [r for r in caplog.records if "user_api_key_auth(): Exception occured" in r.getMessage()]
|
||||
assert len(records) == 1
|
||||
assert records[0].levelno == expected_level
|
||||
assert (records[0].exc_info is not None) is expect_traceback
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue