From c1ec82fbd57ee230def90f3e369f401c4386d651 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Mon, 10 Mar 2025 15:21:04 -0700 Subject: [PATCH 1/6] refactor: instrument body param to bubble up on exception --- litellm/llms/base_llm/chat/transformation.py | 2 + litellm/llms/openai/common_utils.py | 2 + litellm/llms/openai/openai.py | 6 ++- ...odel_prices_and_context_window_backup.json | 40 +++++++++---------- tests/llm_translation/test_openai.py | 31 ++++++++++++++ 5 files changed, 60 insertions(+), 21 deletions(-) diff --git a/litellm/llms/base_llm/chat/transformation.py b/litellm/llms/base_llm/chat/transformation.py index d05b79dd7f..8327a10464 100644 --- a/litellm/llms/base_llm/chat/transformation.py +++ b/litellm/llms/base_llm/chat/transformation.py @@ -51,6 +51,7 @@ class BaseLLMException(Exception): headers: Optional[Union[dict, httpx.Headers]] = None, request: Optional[httpx.Request] = None, response: Optional[httpx.Response] = None, + body: Optional[dict] = None, ): self.status_code = status_code self.message: str = message @@ -67,6 +68,7 @@ class BaseLLMException(Exception): self.response = httpx.Response( status_code=status_code, request=self.request ) + self.body = body super().__init__( self.message ) # Call the base class constructor with the parameters it needs diff --git a/litellm/llms/openai/common_utils.py b/litellm/llms/openai/common_utils.py index 98a55b4bd3..a8412f867b 100644 --- a/litellm/llms/openai/common_utils.py +++ b/litellm/llms/openai/common_utils.py @@ -19,6 +19,7 @@ class OpenAIError(BaseLLMException): request: Optional[httpx.Request] = None, response: Optional[httpx.Response] = None, headers: Optional[Union[dict, httpx.Headers]] = None, + body: Optional[dict] = None, ): self.status_code = status_code self.message = message @@ -39,6 +40,7 @@ class OpenAIError(BaseLLMException): headers=self.headers, request=self.request, response=self.response, + body=body, ) diff --git a/litellm/llms/openai/openai.py b/litellm/llms/openai/openai.py index 3fddca53e7..ca2b8ec6c7 100644 --- a/litellm/llms/openai/openai.py +++ b/litellm/llms/openai/openai.py @@ -828,13 +828,17 @@ class OpenAIChatCompletion(BaseLLM): except Exception as e: exception_response = getattr(e, "response", None) status_code = getattr(e, "status_code", 500) + exception_body = getattr(e, "body", None) error_headers = getattr(e, "headers", None) if error_headers is None and exception_response: error_headers = getattr(exception_response, "headers", None) message = getattr(e, "message", str(e)) raise OpenAIError( - status_code=status_code, message=message, headers=error_headers + status_code=status_code, + message=message, + headers=error_headers, + body=exception_body, ) def streaming( diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index b61ddd4562..b2a08544f9 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -6057,26 +6057,6 @@ "mode": "chat", "supports_tool_choice": true }, - "jamba-large-1.6": { - "max_tokens": 256000, - "max_input_tokens": 256000, - "max_output_tokens": 256000, - "input_cost_per_token": 0.000002, - "output_cost_per_token": 0.000008, - "litellm_provider": "ai21", - "mode": "chat", - "supports_tool_choice": true - }, - "jamba-mini-1.6": { - "max_tokens": 256000, - "max_input_tokens": 256000, - "max_output_tokens": 256000, - "input_cost_per_token": 0.0000002, - "output_cost_per_token": 0.0000004, - "litellm_provider": "ai21", - "mode": "chat", - "supports_tool_choice": true - }, "jamba-1.5-mini": { "max_tokens": 256000, "max_input_tokens": 256000, @@ -6097,6 +6077,26 @@ "mode": "chat", "supports_tool_choice": true }, + "jamba-large-1.6": { + "max_tokens": 256000, + "max_input_tokens": 256000, + "max_output_tokens": 256000, + "input_cost_per_token": 0.000002, + "output_cost_per_token": 0.000008, + "litellm_provider": "ai21", + "mode": "chat", + "supports_tool_choice": true + }, + "jamba-mini-1.6": { + "max_tokens": 256000, + "max_input_tokens": 256000, + "max_output_tokens": 256000, + "input_cost_per_token": 0.0000002, + "output_cost_per_token": 0.0000004, + "litellm_provider": "ai21", + "mode": "chat", + "supports_tool_choice": true + }, "j2-mid": { "max_tokens": 8192, "max_input_tokens": 8192, diff --git a/tests/llm_translation/test_openai.py b/tests/llm_translation/test_openai.py index 172c946636..7bbcea2a23 100644 --- a/tests/llm_translation/test_openai.py +++ b/tests/llm_translation/test_openai.py @@ -391,3 +391,34 @@ def test_openai_chat_completion_streaming_handler_reasoning_content(): ) assert response.choices[0].delta.reasoning_content == "." + + +@pytest.mark.parametrize("sync_mode", [True, False]) +@pytest.mark.parametrize("stream_mode", [True, False]) +@pytest.mark.asyncio +async def test_exception_bubbling_up(sync_mode, stream_mode): + """ + make sure code, param, and type are bubbled up + """ + import litellm + + litellm.set_verbose = True + with pytest.raises(Exception) as exc_info: + if sync_mode: + litellm.completion( + model="gpt-4o-mini", + messages=[{"role": "usera", "content": "hi"}], + stream=stream_mode, + sync_stream=sync_mode, + ) + else: + await litellm.acompletion( + model="gpt-4o-mini", + messages=[{"role": "usera", "content": "hi"}], + stream=stream_mode, + sync_stream=sync_mode, + ) + + assert exc_info.value.code == "invalid_request_error" + assert exc_info.value.param == "messages" + assert exc_info.value.type == "invalid_request_error" From 5f87dc229af00419f5bd68ce08bd929956d795e6 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Mon, 10 Mar 2025 15:27:43 -0700 Subject: [PATCH 2/6] feat(openai.py): bubble all error information back to client --- litellm/exceptions.py | 3 ++- .../litellm_core_utils/exception_mapping_utils.py | 1 + litellm/llms/openai/openai.py | 15 +++++++++++++-- tests/llm_translation/test_openai.py | 4 ++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/litellm/exceptions.py b/litellm/exceptions.py index f4166a5837..6a927f0712 100644 --- a/litellm/exceptions.py +++ b/litellm/exceptions.py @@ -118,6 +118,7 @@ class BadRequestError(openai.BadRequestError): # type: ignore litellm_debug_info: Optional[str] = None, max_retries: Optional[int] = None, num_retries: Optional[int] = None, + body: Optional[dict] = None, ): self.status_code = 400 self.message = "litellm.BadRequestError: {}".format(message) @@ -133,7 +134,7 @@ class BadRequestError(openai.BadRequestError): # type: ignore self.max_retries = max_retries self.num_retries = num_retries super().__init__( - self.message, response=response, body=None + self.message, response=response, body=body ) # Call the base class constructor with the parameters it needs def __str__(self): diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index 1f5e0147b9..91d2f296d0 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -331,6 +331,7 @@ def exception_type( # type: ignore # noqa: PLR0915 model=model, response=getattr(original_exception, "response", None), litellm_debug_info=extra_information, + body=getattr(original_exception, "body", None), ) elif ( "Web server is returning an unknown error" in error_str diff --git a/litellm/llms/openai/openai.py b/litellm/llms/openai/openai.py index ca2b8ec6c7..7935c46293 100644 --- a/litellm/llms/openai/openai.py +++ b/litellm/llms/openai/openai.py @@ -732,10 +732,14 @@ class OpenAIChatCompletion(BaseLLM): error_headers = getattr(e, "headers", None) error_text = getattr(e, "text", str(e)) error_response = getattr(e, "response", None) + error_body = getattr(e, "body", None) if error_headers is None and error_response: error_headers = getattr(error_response, "headers", None) raise OpenAIError( - status_code=status_code, message=error_text, headers=error_headers + status_code=status_code, + message=error_text, + headers=error_headers, + body=error_body, ) async def acompletion( @@ -977,6 +981,7 @@ class OpenAIChatCompletion(BaseLLM): error_headers = getattr(e, "headers", None) status_code = getattr(e, "status_code", 500) error_response = getattr(e, "response", None) + exception_body = getattr(e, "body", None) if error_headers is None and error_response: error_headers = getattr(error_response, "headers", None) if response is not None and hasattr(response, "text"): @@ -984,6 +989,7 @@ class OpenAIChatCompletion(BaseLLM): status_code=status_code, message=f"{str(e)}\n\nOriginal Response: {response.text}", # type: ignore headers=error_headers, + body=exception_body, ) else: if type(e).__name__ == "ReadTimeout": @@ -991,16 +997,21 @@ class OpenAIChatCompletion(BaseLLM): status_code=408, message=f"{type(e).__name__}", headers=error_headers, + body=exception_body, ) elif hasattr(e, "status_code"): raise OpenAIError( status_code=getattr(e, "status_code", 500), message=str(e), headers=error_headers, + body=exception_body, ) else: raise OpenAIError( - status_code=500, message=f"{str(e)}", headers=error_headers + status_code=500, + message=f"{str(e)}", + headers=error_headers, + body=exception_body, ) def get_stream_options( diff --git a/tests/llm_translation/test_openai.py b/tests/llm_translation/test_openai.py index 7bbcea2a23..d248dd28a3 100644 --- a/tests/llm_translation/test_openai.py +++ b/tests/llm_translation/test_openai.py @@ -419,6 +419,6 @@ async def test_exception_bubbling_up(sync_mode, stream_mode): sync_stream=sync_mode, ) - assert exc_info.value.code == "invalid_request_error" - assert exc_info.value.param == "messages" + assert exc_info.value.code == "invalid_value" + assert exc_info.value.param is not None assert exc_info.value.type == "invalid_request_error" From f688fc81387b7ffb5f3c5c87b12c6956d27b9642 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Mon, 10 Mar 2025 15:34:06 -0700 Subject: [PATCH 3/6] feat(proxy_server.py): check code before defaulting to status code --- litellm/proxy/_new_secret_config.yaml | 12 ++++++++++-- litellm/proxy/proxy_server.py | 26 +++++++++++++------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/litellm/proxy/_new_secret_config.yaml b/litellm/proxy/_new_secret_config.yaml index eac1e6a6da..e22888f298 100644 --- a/litellm/proxy/_new_secret_config.yaml +++ b/litellm/proxy/_new_secret_config.yaml @@ -1,4 +1,12 @@ model_list: - - model_name: llama3.2-vision + - model_name: gpt-3.5-turbo litellm_params: - model: ollama/llama3.2-vision \ No newline at end of file + model: gpt-3.5-turbo + - model_name: gpt-4o + litellm_params: + model: azure/gpt-4o + api_key: os.environ/AZURE_API_KEY + api_base: os.environ/AZURE_API_BASE + +litellm_settings: + fallbacks: [{"gpt-3.5-turbo": ["gpt-4o"]}] diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 99b6f4ea54..0dd3aabe98 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -3716,7 +3716,7 @@ async def chat_completion( # noqa: PLR0915 message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), headers=headers, ) @@ -3929,7 +3929,7 @@ async def completion( # noqa: PLR0915 message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -4138,7 +4138,7 @@ async def embeddings( # noqa: PLR0915 message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -4257,7 +4257,7 @@ async def image_generation( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -4518,7 +4518,7 @@ async def audio_transcriptions( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -4667,7 +4667,7 @@ async def get_assistants( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -4765,7 +4765,7 @@ async def create_assistant( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -4862,7 +4862,7 @@ async def delete_assistant( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -4959,7 +4959,7 @@ async def create_threads( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -5055,7 +5055,7 @@ async def get_thread( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -5154,7 +5154,7 @@ async def add_messages( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -5249,7 +5249,7 @@ async def get_messages( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) @@ -5358,7 +5358,7 @@ async def run_thread( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "status_code", 500), + code=getattr(e, "code", getattr(e, "status_code", 500)), ) From bfbe26b91d507b7c3bf1ffd10fd520bdc90c292b Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Mon, 10 Mar 2025 15:59:06 -0700 Subject: [PATCH 4/6] feat(azure.py): add azure bad request error support --- .../exception_mapping_utils.py | 3 ++ litellm/llms/azure/azure.py | 15 +++++++-- litellm/llms/azure/common_utils.py | 2 ++ tests/llm_translation/test_openai.py | 31 ------------------ tests/local_testing/test_exceptions.py | 32 +++++++++++++++++++ 5 files changed, 49 insertions(+), 34 deletions(-) diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index 91d2f296d0..7a0cffab7b 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -422,6 +422,7 @@ def exception_type( # type: ignore # noqa: PLR0915 llm_provider=custom_llm_provider, response=getattr(original_exception, "response", None), litellm_debug_info=extra_information, + body=getattr(original_exception, "body", None), ) elif original_exception.status_code == 429: exception_mapping_worked = True @@ -1961,6 +1962,7 @@ def exception_type( # type: ignore # noqa: PLR0915 model=model, litellm_debug_info=extra_information, response=getattr(original_exception, "response", None), + body=getattr(original_exception, "body", None), ) elif ( "The api_key client option must be set either by passing api_key to the client or by setting" @@ -1992,6 +1994,7 @@ def exception_type( # type: ignore # noqa: PLR0915 model=model, litellm_debug_info=extra_information, response=getattr(original_exception, "response", None), + body=getattr(original_exception, "body", None), ) elif original_exception.status_code == 401: exception_mapping_worked = True diff --git a/litellm/llms/azure/azure.py b/litellm/llms/azure/azure.py index 5294bd7141..dcd5af7b96 100644 --- a/litellm/llms/azure/azure.py +++ b/litellm/llms/azure/azure.py @@ -540,10 +540,14 @@ class AzureChatCompletion(BaseLLM): status_code = getattr(e, "status_code", 500) error_headers = getattr(e, "headers", None) error_response = getattr(e, "response", None) + error_body = getattr(e, "body", None) if error_headers is None and error_response: error_headers = getattr(error_response, "headers", None) raise AzureOpenAIError( - status_code=status_code, message=str(e), headers=error_headers + status_code=status_code, + message=str(e), + headers=error_headers, + body=error_body, ) async def acompletion( @@ -649,6 +653,7 @@ class AzureChatCompletion(BaseLLM): raise AzureOpenAIError(status_code=500, message=str(e)) except Exception as e: message = getattr(e, "message", str(e)) + body = getattr(e, "body", None) ## LOGGING logging_obj.post_call( input=data["messages"], @@ -659,7 +664,7 @@ class AzureChatCompletion(BaseLLM): if hasattr(e, "status_code"): raise e else: - raise AzureOpenAIError(status_code=500, message=message) + raise AzureOpenAIError(status_code=500, message=message, body=body) def streaming( self, @@ -805,10 +810,14 @@ class AzureChatCompletion(BaseLLM): error_headers = getattr(e, "headers", None) error_response = getattr(e, "response", None) message = getattr(e, "message", str(e)) + error_body = getattr(e, "body", None) if error_headers is None and error_response: error_headers = getattr(error_response, "headers", None) raise AzureOpenAIError( - status_code=status_code, message=message, headers=error_headers + status_code=status_code, + message=message, + headers=error_headers, + body=error_body, ) async def aembedding( diff --git a/litellm/llms/azure/common_utils.py b/litellm/llms/azure/common_utils.py index 2a96f5c39c..43f3480ed6 100644 --- a/litellm/llms/azure/common_utils.py +++ b/litellm/llms/azure/common_utils.py @@ -17,6 +17,7 @@ class AzureOpenAIError(BaseLLMException): request: Optional[httpx.Request] = None, response: Optional[httpx.Response] = None, headers: Optional[Union[httpx.Headers, dict]] = None, + body: Optional[dict] = None, ): super().__init__( status_code=status_code, @@ -24,6 +25,7 @@ class AzureOpenAIError(BaseLLMException): request=request, response=response, headers=headers, + body=body, ) diff --git a/tests/llm_translation/test_openai.py b/tests/llm_translation/test_openai.py index d248dd28a3..172c946636 100644 --- a/tests/llm_translation/test_openai.py +++ b/tests/llm_translation/test_openai.py @@ -391,34 +391,3 @@ def test_openai_chat_completion_streaming_handler_reasoning_content(): ) assert response.choices[0].delta.reasoning_content == "." - - -@pytest.mark.parametrize("sync_mode", [True, False]) -@pytest.mark.parametrize("stream_mode", [True, False]) -@pytest.mark.asyncio -async def test_exception_bubbling_up(sync_mode, stream_mode): - """ - make sure code, param, and type are bubbled up - """ - import litellm - - litellm.set_verbose = True - with pytest.raises(Exception) as exc_info: - if sync_mode: - litellm.completion( - model="gpt-4o-mini", - messages=[{"role": "usera", "content": "hi"}], - stream=stream_mode, - sync_stream=sync_mode, - ) - else: - await litellm.acompletion( - model="gpt-4o-mini", - messages=[{"role": "usera", "content": "hi"}], - stream=stream_mode, - sync_stream=sync_mode, - ) - - assert exc_info.value.code == "invalid_value" - assert exc_info.value.param is not None - assert exc_info.value.type == "invalid_request_error" diff --git a/tests/local_testing/test_exceptions.py b/tests/local_testing/test_exceptions.py index 0b4f828054..e68d368779 100644 --- a/tests/local_testing/test_exceptions.py +++ b/tests/local_testing/test_exceptions.py @@ -1205,3 +1205,35 @@ def test_context_window_exceeded_error_from_litellm_proxy(): } with pytest.raises(litellm.ContextWindowExceededError): extract_and_raise_litellm_exception(**args) + + +@pytest.mark.parametrize("sync_mode", [True, False]) +@pytest.mark.parametrize("stream_mode", [True, False]) +@pytest.mark.parametrize("model", ["azure/gpt-4o"]) # "gpt-4o-mini", +@pytest.mark.asyncio +async def test_exception_bubbling_up(sync_mode, stream_mode, model): + """ + make sure code, param, and type are bubbled up + """ + import litellm + + litellm.set_verbose = True + with pytest.raises(Exception) as exc_info: + if sync_mode: + litellm.completion( + model=model, + messages=[{"role": "usera", "content": "hi"}], + stream=stream_mode, + sync_stream=sync_mode, + ) + else: + await litellm.acompletion( + model=model, + messages=[{"role": "usera", "content": "hi"}], + stream=stream_mode, + sync_stream=sync_mode, + ) + + assert exc_info.value.code == "invalid_value" + assert exc_info.value.param is not None + assert exc_info.value.type == "invalid_request_error" From 01aa536716d1b88241c78cfd00bb2eeab240e456 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Mon, 10 Mar 2025 21:46:05 -0700 Subject: [PATCH 5/6] fix: fix test --- litellm/proxy/_new_secret_config.yaml | 7 ++++++- litellm/proxy/_types.py | 5 +++-- litellm/proxy/proxy_server.py | 18 ++++++++++++------ tests/test_fallbacks.py | 2 +- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/litellm/proxy/_new_secret_config.yaml b/litellm/proxy/_new_secret_config.yaml index e22888f298..83e71c55e1 100644 --- a/litellm/proxy/_new_secret_config.yaml +++ b/litellm/proxy/_new_secret_config.yaml @@ -7,6 +7,11 @@ model_list: model: azure/gpt-4o api_key: os.environ/AZURE_API_KEY api_base: os.environ/AZURE_API_BASE - + - model_name: fake-openai-endpoint-5 + litellm_params: + model: openai/my-fake-model + api_key: my-fake-key + api_base: https://exampleopenaiendpoint-production.up.railway.app/ + timeout: 1 litellm_settings: fallbacks: [{"gpt-3.5-turbo": ["gpt-4o"]}] diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index 6bf2ef9068..f37bbd7d09 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -1994,13 +1994,14 @@ class ProxyException(Exception): message: str, type: str, param: Optional[str], - code: Optional[Union[int, str]] = None, + code: Optional[Union[int, str]] = None, # maps to status code headers: Optional[Dict[str, str]] = None, + openai_code: Optional[str] = None, # maps to 'code' in openai ): self.message = str(message) self.type = type self.param = param - + self.openai_code = openai_code or code # If we look on official python OpenAI lib, the code should be a string: # https://github.com/openai/openai-python/blob/195c05a64d39c87b2dfdf1eca2d339597f1fce03/src/openai/types/shared/error_object.py#L11 # Related LiteLLM issue: https://github.com/BerriAI/litellm/discussions/4834 diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 0dd3aabe98..a631ba963b 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -3716,7 +3716,8 @@ async def chat_completion( # noqa: PLR0915 message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "code", getattr(e, "status_code", 500)), + openai_code=getattr(e, "code", None), + code=getattr(e, "status_code", 500), headers=headers, ) @@ -3929,7 +3930,8 @@ async def completion( # noqa: PLR0915 message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "code", getattr(e, "status_code", 500)), + openai_code=getattr(e, "code", None), + code=getattr(e, "status_code", 500), ) @@ -4138,7 +4140,8 @@ async def embeddings( # noqa: PLR0915 message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "code", getattr(e, "status_code", 500)), + openai_code=getattr(e, "code", None), + code=getattr(e, "status_code", 500), ) @@ -4257,7 +4260,8 @@ async def image_generation( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "code", getattr(e, "status_code", 500)), + openai_code=getattr(e, "code", None), + code=getattr(e, "status_code", 500), ) @@ -4518,7 +4522,8 @@ async def audio_transcriptions( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "code", getattr(e, "status_code", 500)), + openai_code=getattr(e, "code", None), + code=getattr(e, "status_code", 500), ) @@ -4667,7 +4672,8 @@ async def get_assistants( message=getattr(e, "message", error_msg), type=getattr(e, "type", "None"), param=getattr(e, "param", "None"), - code=getattr(e, "code", getattr(e, "status_code", 500)), + openai_code=getattr(e, "code", None), + code=getattr(e, "status_code", 500), ) diff --git a/tests/test_fallbacks.py b/tests/test_fallbacks.py index aab8e985bd..449778826b 100644 --- a/tests/test_fallbacks.py +++ b/tests/test_fallbacks.py @@ -193,7 +193,7 @@ async def test_chat_completion_with_timeout(): start_time = time.time() response, headers = await chat_completion( session=session, - key="sk-1234", + key="sk-PIp1h0RekR", model=model, messages=messages, num_retries=0, From 41b0404ae1a8a3f05bc45fd4ffb89f61bf0185b5 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Mon, 10 Mar 2025 22:00:50 -0700 Subject: [PATCH 6/6] test: fix test --- tests/test_fallbacks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_fallbacks.py b/tests/test_fallbacks.py index 449778826b..aab8e985bd 100644 --- a/tests/test_fallbacks.py +++ b/tests/test_fallbacks.py @@ -193,7 +193,7 @@ async def test_chat_completion_with_timeout(): start_time = time.time() response, headers = await chat_completion( session=session, - key="sk-PIp1h0RekR", + key="sk-1234", model=model, messages=messages, num_retries=0,