From f04808e293669bb353158f69d6e75eda27a23db4 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 27 Jun 2025 15:49:07 -0700 Subject: [PATCH] [Bug Fix] Exception mapping for context window exceeded - should catch anthropic exceptions (#12113) * fix is is_error_str_context_window_exceeded * test_is_error_str_context_window_exceeded * fix is_error_str_context_window_exceeded --- .../exception_mapping_utils.py | 27 +++++++++++----- .../test_exception_mapping_utils.py | 31 +++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index f38883bb179..ad5060c533b 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -44,6 +44,25 @@ class ExceptionCheckers: return False return "429" in error_str or "rate limit" in error_str.lower() + + + @staticmethod + def is_error_str_context_window_exceeded(error_str: str) -> bool: + """ + Check if an error string indicates a context window exceeded error. + """ + _error_str_lowercase = error_str.lower() + known_exception_substrings = [ + "exceed context limit", + "this model's maximum context length is", + "string too long. expected a string with maximum length", + "model's maximum context limit", + "is longer than the model's context length", + ] + for substring in known_exception_substrings: + if substring in _error_str_lowercase: + return True + return False def get_error_message(error_obj) -> Optional[str]: @@ -304,13 +323,7 @@ def exception_type( # type: ignore # noqa: PLR0915 llm_provider=custom_llm_provider, response=getattr(original_exception, "response", None), ) - elif ( - "This model's maximum context length is" in error_str - or "string too long. Expected a string with maximum length" - in error_str - or "model's maximum context limit" in error_str - or "is longer than the model's context length" in error_str - ): + elif ExceptionCheckers.is_error_str_context_window_exceeded(error_str): exception_mapping_worked = True raise ContextWindowExceededError( message=f"ContextWindowExceededError: {exception_provider} - {message}", 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 new file mode 100644 index 00000000000..42e65612a96 --- /dev/null +++ b/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py @@ -0,0 +1,31 @@ +import pytest + +from litellm.litellm_core_utils.exception_mapping_utils import ExceptionCheckers + +# Test cases for is_error_str_context_window_exceeded +# Tuple format: (error_message, expected_result) +context_window_test_cases = [ + # Positive cases (should return True) + ("An error occurred: The input exceeds the model's maximum context limit of 8192 tokens.", True), + ("Some text before, this model's maximum context length is 4096 tokens. Some text after.", True), + ("Validation Error: string too long. expected a string with maximum length 1000.", True), + ("Your prompt is longer than the model's context length of 2048.", True), + ("AWS Bedrock Error: The request payload size has exceed context limit.", True), + + # Test case insensitivity + ("ERROR: THIS MODEL'S MAXIMUM CONTEXT LENGTH IS 1024.", True), + + # Negative cases (should return False) + ("A generic API error occurred.", False), + ("Invalid API Key provided.", False), + ("Rate limit reached for requests.", False), + ("The context is large, but acceptable.", False), + ("", False), # Empty string +] + +@pytest.mark.parametrize("error_str, expected", context_window_test_cases) +def test_is_error_str_context_window_exceeded(error_str, expected): + """ + Tests the is_error_str_context_window_exceeded function with various error strings. + """ + assert ExceptionCheckers.is_error_str_context_window_exceeded(error_str) == expected \ No newline at end of file