-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from PCain02/Exception_Handling
feat: Add Exception Handling for LiteLLM
- Loading branch information
Showing
3 changed files
with
207 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
"""Define exceptions for the input errors in the command line.""" | ||
|
||
import sys | ||
|
||
# from rich.console import Console (ask if i need to import this?) i dont think i do because i pass it as an atg | ||
|
||
|
||
def get_litellm_traceback(console) -> None: | ||
"""Print the traceback of the last exception.""" | ||
exc_type, exc_obj, _ = sys.exc_info() | ||
|
||
if exc_type is None: | ||
return | ||
# List of litellm exception types and their explanations | ||
litellm_exceptions = { | ||
"NotFoundError": "LLM resource not found. Please check your model and/or endpoint.", | ||
"AuthenticationError": "API authentication failed. Please verify your API key.", | ||
"RateLimitError": "Rate limit exceeded. Wait and retry or check API key.\nNOTE: This error can sometimes be caused by an invalid API key.", | ||
"InvalidRequestError": "Malformed API request. Please review parameters.", | ||
"APIError": "Internal LLM API error. Retry later.", | ||
"APIConnectionError": "Connection failed. \nNOTE: This error can sometimes be caused by an invalid server URL. Verify your server URL.", | ||
} | ||
|
||
# if statements to display exceptions | ||
if exc_type.__name__ in litellm_exceptions: | ||
console.print( | ||
f"[bold red]Exception Type: {exc_type.__name__}[/bold red]" | ||
) | ||
console.print(f"Explanation: {litellm_exceptions[exc_type.__name__]}") | ||
else: | ||
# default behavior for non-litellm exceptions | ||
console.print( | ||
f"[bold red]Exception Type: {exc_type.__name__}[/bold red]" | ||
) | ||
console.print(f"Error Message: {exc_obj!s}") | ||
|
||
# general purpose ouput as a backup | ||
console.print( | ||
"\n[bold red]If your issue persists, ensure the model you entered is correct, such as:[/bold red]" | ||
) | ||
console.print("[bold blue]- anthropic/claude-3-haiku-20240307[/bold blue]") | ||
console.print("[bold blue]- anthropic/claude-3-opus-20240229[/bold blue]") | ||
console.print("[bold blue]- groq/llama3-8b-8192[/bold blue]") | ||
console.print( | ||
"[bold blue]- openrouter/meta-llama/llama-3.1-8b-instruct:free[/bold blue]" | ||
) | ||
|
||
console.print( | ||
"\n[bold red]Please visit [bold blue]https://docs.litellm.ai/docs/providers [/bold blue]for more valid LiteLLM models[bold red]" | ||
) | ||
|
||
console.print( | ||
"\n[bold red]For server connectivity issues, please visit [bold blue]https://docs.litellm.ai/docs/simple_proxy [/bold blue]for a valid LiteLLM proxy.[/bold red]" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
"""Test Suite for Exceptions Module.""" | ||
|
||
from unittest.mock import patch | ||
|
||
from rich.console import Console | ||
|
||
from execexam.exceptions import get_litellm_traceback | ||
|
||
# Create a console object for testing | ||
console = Console() | ||
|
||
|
||
def test_not_found_error(): | ||
"""Test case for NotFoundError.""" | ||
# Mocking sys.exc_info to simulate a NotFoundError exception | ||
with patch( | ||
"sys.exc_info", | ||
return_value=( | ||
type("NotFoundError", (Exception,), {}), | ||
Exception("Resource not found"), | ||
None, | ||
), | ||
): | ||
with patch("rich.console.Console.print") as mock_print: | ||
# Call the function to get the traceback | ||
get_litellm_traceback(console) | ||
# Assert that the correct messages are printed for NotFoundError | ||
mock_print.assert_any_call( | ||
"[bold red]Exception Type: NotFoundError[/bold red]" | ||
) | ||
mock_print.assert_any_call( | ||
"Explanation: LLM resource not found. Please check your model and/or endpoint." | ||
) | ||
|
||
|
||
def test_authentication_error(): | ||
"""Test case for AuthenticationError.""" | ||
# Mocking sys.exc_info to simulate an AuthenticationError exception | ||
with patch( | ||
"sys.exc_info", | ||
return_value=( | ||
type("AuthenticationError", (Exception,), {}), | ||
Exception("Authentication failed"), | ||
None, | ||
), | ||
): | ||
with patch("rich.console.Console.print") as mock_print: | ||
# Call the function to get the traceback | ||
get_litellm_traceback(console) | ||
# Assert that the correct messages are printed for AuthenticationError | ||
mock_print.assert_any_call( | ||
"[bold red]Exception Type: AuthenticationError[/bold red]" | ||
) | ||
mock_print.assert_any_call( | ||
"Explanation: API authentication failed. Please verify your API key." | ||
) | ||
|
||
|
||
def test_rate_limit_error(): | ||
"""Test case for RateLimitError.""" | ||
# Mocking sys.exc_info to simulate a RateLimitError exception | ||
with patch( | ||
"sys.exc_info", | ||
return_value=( | ||
type("RateLimitError", (Exception,), {}), | ||
Exception("Rate limit exceeded"), | ||
None, | ||
), | ||
): | ||
with patch("rich.console.Console.print") as mock_print: | ||
# Call the function to get the traceback | ||
get_litellm_traceback(console) | ||
# Assert that the correct messages are printed for RateLimitError | ||
mock_print.assert_any_call( | ||
"[bold red]Exception Type: RateLimitError[/bold red]" | ||
) | ||
mock_print.assert_any_call( | ||
"Explanation: Rate limit exceeded. Wait and retry or check API key.\nNOTE: This error can sometimes be caused by an invalid API key." | ||
) |