diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index 022873214a8..8a28106810f 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -2462,7 +2462,7 @@ def exception_type( or custom_llm_provider in litellm.openai_compatible_providers or custom_llm_provider == "mistral" or custom_llm_provider == "runwayml" - ): + ) and (hasattr(original_exception, "request") or hasattr(original_exception, "status_code")): _map_openai_exception( model=model, original_exception=mappable_exception, 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 9b2568e390f..491b76bef3e 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 @@ -972,6 +972,35 @@ def test_an_unmapped_exception_with_no_model_or_provider_is_a_connection_error(q assert "boom" in raised.value.message +def test_unmapped_sdk_exception_includes_bug_report_link(quiet_exception_mapping): + with pytest.raises(litellm.APIConnectionError) as raised: + exception_type( + model="gpt-4o", + custom_llm_provider="openai", + original_exception=ValueError("boom"), + completion_kwargs={}, + extra_kwargs={}, + ) + + assert "https://github.com/BerriAI/litellm/issues/new?" in str(raised.value) + assert "ValueError" in str(raised.value) + + +def test_unmapped_sdk_exception_bug_report_link_can_be_disabled(quiet_exception_mapping, monkeypatch): + monkeypatch.setenv("LITELLM_DISABLE_BUG_REPORT_LINK", "true") + + with pytest.raises(litellm.APIConnectionError) as raised: + exception_type( + model="gpt-4o", + custom_llm_provider="openai", + original_exception=ValueError("boom"), + completion_kwargs={}, + extra_kwargs={}, + ) + + assert "https://github.com/BerriAI/litellm/issues/new?" not in str(raised.value) + + def _raise_and_map(model: str | None, original_exception: Exception, custom_llm_provider: str | None) -> None: """Calls exception_type() from inside the except block, as litellm/main.py does, so traceback.format_exc() has a real stack."""