diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index 1517d1e776d..107cdf39bfa 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -197,12 +197,22 @@ def extract_and_raise_litellm_exception( exception_name = exception_name.strip().replace("litellm.", "") raised_exception_obj = getattr(litellm, exception_name, None) if raised_exception_obj: - raise raised_exception_obj( - message=error_str, - llm_provider=custom_llm_provider, - model=model, - response=response, - ) + # Try with response parameter first, fall back to without it + # Some exceptions (e.g., APIConnectionError) don't accept response param + try: + raise raised_exception_obj( + message=error_str, + llm_provider=custom_llm_provider, + model=model, + response=response, + ) + except TypeError: + # Exception doesn't accept response parameter + raise raised_exception_obj( + message=error_str, + llm_provider=custom_llm_provider, + model=model, + ) def exception_type( # type: ignore # noqa: PLR0915 diff --git a/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py b/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py index 9e742a83c6a..c7ad18cfb0c 100644 --- a/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py +++ b/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py @@ -12,6 +12,7 @@ sys.path.insert( from litellm.litellm_core_utils.exception_mapping_utils import ( ExceptionCheckers, exception_type, + extract_and_raise_litellm_exception, ) # Test cases for is_error_str_context_window_exceeded @@ -269,3 +270,79 @@ def test_vertex_ai_rate_limit_error_mapping(error_message, should_raise_rate_lim original_exception=original_exception, custom_llm_provider=custom_llm_provider, ) + + +class TestExtractAndRaiseLitellmException: + """Tests for extract_and_raise_litellm_exception function""" + + def test_extract_and_raise_api_connection_error_without_response(self): + """ + Test that APIConnectionError can be raised without response parameter. + + This is a regression test for the bug where extract_and_raise_litellm_exception + would fail with TypeError when trying to raise APIConnectionError with a + response parameter, since APIConnectionError doesn't accept that parameter. + + Relevant Issue: https://github.com/BerriAI/litellm/issues/XXXXX + """ + error_str = "litellm.APIConnectionError: GeminiException - some error message" + + with pytest.raises(litellm.APIConnectionError) as excinfo: + extract_and_raise_litellm_exception( + response=None, + error_str=error_str, + model="gemini/gemini-3-pro-preview", + custom_llm_provider="gemini", + ) + + assert "APIConnectionError" in str(excinfo.value) + + def test_extract_and_raise_bad_request_error_with_response(self): + """ + Test that BadRequestError can be raised with response parameter. + + BadRequestError does accept the response parameter, so this should work. + """ + error_str = "litellm.BadRequestError: Invalid request format" + + with pytest.raises(litellm.BadRequestError) as excinfo: + extract_and_raise_litellm_exception( + response=None, + error_str=error_str, + model="gpt-4", + custom_llm_provider="openai", + ) + + assert "BadRequestError" in str(excinfo.value) + + def test_extract_and_raise_context_window_exceeded_error(self): + """ + Test that ContextWindowExceededError can be raised. + """ + error_str = "litellm.ContextWindowExceededError: Token limit exceeded" + + with pytest.raises(litellm.ContextWindowExceededError) as excinfo: + extract_and_raise_litellm_exception( + response=None, + error_str=error_str, + model="gpt-4", + custom_llm_provider="openai", + ) + + assert "ContextWindowExceededError" in str(excinfo.value) + + def test_no_exception_raised_for_non_litellm_error(self): + """ + Test that no exception is raised for non-litellm error strings. + """ + error_str = "Some generic error that is not a litellm exception" + + # Should not raise any exception + result = extract_and_raise_litellm_exception( + response=None, + error_str=error_str, + model="gpt-4", + custom_llm_provider="openai", + ) + + assert result is None