How to Handle LLMError and Provider Exceptions in aisuite
aisuite unifies all provider-specific SDK errors into LLMError and ASRError exceptions, allowing developers to catch a single exception type while preserving access to underlying errors via the __cause__ attribute.
aisuite simplifies interactions with multiple LLM and ASR providers by normalizing their disparate error handling into a consistent interface. Understanding how the library wraps provider-specific exceptions into LLMError and ASRError is essential for building resilient AI applications. This guide explains the exception hierarchy defined in the core provider module and demonstrates how to implement robust error handling strategies using the actual source implementation.
The Unified Exception Hierarchy
All concrete provider implementations in aisuite inherit from the abstract Provider class defined in [aisuite/provider.py](https://github.com/andrewyng/aisuite/blob/main/aisuite/provider.py#L10-L16). This base class establishes two primary exception types that standardize error handling across the library:
LLMError– Raised whenever a provider encounters a problem during chat completion requests, including synchronous, asynchronous, and streaming calls.ASRError– Raised specifically for audio transcription-related failures.
This design ensures that application code can catch a single exception type regardless of which underlying provider (OpenAI, Anthropic, Together, etc.) generated the error. The abstraction eliminates the need to import and handle multiple provider-specific exception classes in your business logic.
How Providers Wrap SDK Errors
Each provider implementation follows a consistent pattern to isolate upstream SDK exceptions. Rather than allowing raw provider errors to propagate, aisuite wrappers catch all exceptions and re-raise them as LLMError instances while preserving the original traceback.
In [aisuite/providers/openai_provider.py](https://github.com/andrewyng/aisuite/blob/main/aisuite/providers/openai_provider.py), this pattern appears as:
try:
# Call the underlying SDK
response = openai.ChatCompletion.create(...)
except Exception as e: # catches any provider-specific error
raise LLMError(f"An error occurred: {e}") from e
The raise ... from e syntax maintains the exception chain, storing the original OpenAI error in the __cause__ attribute. This approach is replicated across all provider implementations including anthropic_provider, together_provider, and xai_provider, ensuring consistent behavior regardless of the backend service.
Catching Generic LLM Errors
For most use cases, catching LLMError provides sufficient protection against LLM failures. This handles network timeouts, authentication errors, invalid parameters, and service outages uniformly.
from aisuite.client import AISuiteClient
from aisuite.provider import LLMError
client = AISuiteClient(provider="openai", config={"api_key": "..."})
try:
response = client.chat(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}]
)
print(response.content)
except LLMError as e:
# Generic handling: log, retry, or fallback to another provider
print(f"LLM request failed: {e}")
This pattern applies to all chat completion methods including chat(), achat(), and streaming variants.
Accessing Provider-Specific Error Details
When you need to implement provider-specific logic—such as exponential backoff for rate limits or special handling for authentication errors—inspect the __cause__ attribute of the caught LLMError. This attribute contains the original SDK exception raised by the provider.
import openai
from aisuite.provider import LLMError
try:
reply = client.chat(model="gpt-4o", messages=messages)
except LLMError as err:
if err.__cause__ and isinstance(err.__cause__, openai.error.RateLimitError):
# Implement exponential backoff or switch to backup provider
handle_rate_limit()
elif err.__cause__ and isinstance(err.__cause__, anthropic.exceptions.AnthropicError):
# Handle Anthropic-specific error logic
handle_anthropic_issue()
else:
# Fallback for other errors
logger.error(f"Unexpected LLM error: {err}")
This technique allows granular error handling without sacrificing the benefits of aisuite's unified interface.
Handling Streaming Errors
When working with streaming APIs, aisuite raises LLMError if a provider has not implemented the chat_completions_create_stream method. The abstract Provider class in [aisuite/provider.py](https://github.com/andrewyng/aisuite/blob/main/aisuite/provider.py#L54-L56) provides a default implementation that deliberately throws this error to signal unsupported functionality:
try:
async for chunk in client.achat_stream(model="gpt-4o", messages=messages):
process(chunk)
except LLMError as err:
# Provider does not support streaming; revert to non-streaming call
logger.warning(f"Streaming unsupported: {err}")
response = client.chat(model="gpt-4o", messages=messages)
process_response(response)
This pattern enables graceful degradation when providers lack streaming capabilities.
Handling ASR Errors
For audio transcription workflows, catch ASRError to handle failures in speech-to-text operations. The Audio.Transcription base class raises this exception when providers do not implement transcription capabilities or when the underlying ASR service fails.
from aisuite.provider import ASRError
try:
transcription = client.transcribe_audio("audio.wav")
print(transcription.text)
except ASRError as e:
# Handle transcription failures: invalid file format, service unavailable, etc.
logger.error(f"Audio transcription failed: {e}")
Summary
- Unified exception types:
LLMErrorandASRErrorinaisuite/provider.pystandardize error handling across all providers. - Exception chaining: Providers wrap SDK-specific errors using
raise LLMError(...) from e, preserving the original exception in__cause__. - Generic handling: Catch
LLMErrorto handle all LLM-related failures without provider-specific imports. - Granular inspection: Access
err.__cause__to implement provider-specific logic like rate limit handling. - Streaming detection: Unsupported streaming operations raise
LLMErrorvia the defaultProvider.chat_completions_create_streamimplementation.
Frequently Asked Questions
What is the difference between LLMError and ASRError?
LLMError handles failures in text generation and chat completion workflows across all language model providers, while ASRError specifically handles audio transcription failures in speech-to-text operations. Both inherit from Python's standard Exception class and are defined in aisuite/provider.py, but they operate in distinct domains to allow separate error handling strategies for text versus audio processing.
How do I handle rate limiting from specific providers like OpenAI?
Catch LLMError and inspect the __cause__ attribute to identify the specific SDK exception. For OpenAI rate limits, check if isinstance(err.__cause__, openai.error.RateLimitError) returns True, then implement retry logic with exponential backoff or switch to a backup provider. This approach maintains provider-agnostic code structure while enabling targeted handling of transient errors.
What happens if a provider does not support streaming?
The abstract Provider class raises LLMError with a clear message indicating that streaming is not implemented. You can catch this exception in your application code and fall back to synchronous client.chat() calls. This pattern allows you to attempt streaming optimizations while maintaining compatibility with providers that only support standard request-response patterns.
Can I catch the original SDK exception directly instead of LLMError?
While technically possible by importing specific provider SDKs, aisuite intentionally discourages this pattern. All provider implementations wrap native exceptions into LLMError before propagation, meaning you should always catch LLMError first and inspect err.__cause__ for provider-specific details. This ensures your error handling remains functional when switching between providers without code modifications.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →