How to Handle LLMError and Provider-Specific Exceptions in aisuite

All provider errors in aisuite are unified under the LLMError exception class, allowing you to catch any LLM failure with a single handler while still accessing the original SDK exception through the __cause__ attribute for provider-specific logic.

When building applications with the andrewyng/aisuite library, you need a robust strategy to handle failures from multiple LLM backends. The framework abstracts OpenAI, Anthropic, and other providers behind a unified interface, and this abstraction extends to error handling through custom exception types defined in the core provider module.

The Unified Exception Model

aisuite defines a provider-agnostic error architecture in [aisuite/provider.py](https://github.com/andrewyng/aisuite/blob/main/aisuite/provider.py). The abstract Provider class declares two primary exception types that all concrete implementations use:

  • LLMError – Raised whenever a provider encounters a problem during chat completion requests (synchronous, asynchronous, or streaming).
  • ASRError – Raised for audio transcription-related failures.

This design ensures that application code can handle errors from any provider without importing multiple SDK-specific exception classes.

How Providers Wrap SDK Exceptions

Each concrete provider implementation wraps low-level SDK exceptions into the unified LLMError type before propagating them. This preserves the original exception chain while presenting a consistent surface API.

In [aisuite/providers/openai_provider.py](https://github.com/andrewyng/aisuite/blob/main/aisuite/providers/openai_provider.py) and similar provider files, you will find this pattern:

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 preserves the original exception as the cause, making it accessible via the __cause__ attribute for debugging or provider-specific handling.

Catching and Handling LLMError

Because LLMError is the public exception type, your application code should catch it to handle any LLM-related failure generically.

Basic Error Handling

Import LLMError from the provider module and wrap your client calls:

from aisuite.client import AISuiteClient
from aisuite.provider import LLMError

client = AISuiteClient(provider="openai", config={...})

try:
    response = client.chat(model="gpt-4o", messages=[{"role": "user", "content": "Hello"}])
    print(response.content)
except LLMError as e:
    # Generic handling (e.g., retry, fallback)

    print(f"LLM failed: {e}")

Inspecting Provider-Specific Errors

If you need to react to a specific provider's error (e.g., rate limits, authentication failures), inspect the underlying cause via the exception's __cause__ attribute:

import openai
from aisuite.provider import LLMError

try:
    reply = client.chat(model="gpt-4o", messages=msgs)
except LLMError as err:
    if isinstance(err.__cause__, openai.error.RateLimitError):
        # Exponential back-off or switch provider

        handle_rate_limit()
    elif isinstance(err.__cause__, anthropic.exceptions.AnthropicError):
        # Anthropic-specific logic

        handle_anthropic_issue()
    else:
        # Fallback for other errors

        fallback()

This approach maintains the abstraction boundary while giving you access to SDK-specific error properties when necessary.

Handling Streaming and ASR Exceptions

The unified exception model applies to streaming and audio transcription workflows as well.

Streaming Errors

When using streaming APIs, the abstract Provider class in [aisuite/provider.py](https://github.com/andrewyng/aisuite/blob/main/aisuite/provider.py#L54-L56) raises LLMError if a provider does not implement chat_completions_create_stream:

from aisuite.provider import LLMError

try:
    async for chunk in client.achat_stream(model="gpt-4o", messages=msgs):
        print(chunk.delta.content, end="")
except LLMError as e:
    # Provider does not support streaming; revert to non-streaming call

    response = client.chat(model="gpt-4o", messages=msgs)
    print(response.content)

Audio Transcription Errors

For ASR calls, catch ASRError to handle transcription failures:

from aisuite.provider import ASRError

try:
    transcription = client.transcribe_audio("audio.wav")
except ASRError as e:
    print(f"Audio transcription failed: {e}")

Implementation Reference

These key source files demonstrate the error handling implementation:

Summary

  • Unified error type: LLMError (and ASRError for audio) provides a consistent exception interface across all providers.
  • Exception chaining: Provider-specific SDK errors are wrapped using raise LLMError(...) from e, preserving the original exception in __cause__.
  • Stream support detection: The default Provider.chat_completions_create_stream raises LLMError when streaming is not implemented.
  • Granular control: Inspect err.__cause__ to access underlying SDK exceptions for provider-specific error handling.
  • Async compatibility: The error model applies identically to both synchronous and asynchronous client calls.

Frequently Asked Questions

What is the difference between LLMError and ASRError in aisuite?

LLMError handles failures from chat completion requests across all text-based models, while ASRError specifically handles audio transcription failures. Both are defined in aisuite/provider.py and follow the same wrapping pattern, but they target different functionality domains within the library.

How do I access the original provider error after catching LLMError?

Access the original SDK exception through the __cause__ attribute of the caught LLMError instance. For example, isinstance(err.__cause__, openai.error.RateLimitError) lets you detect OpenAI-specific rate limits while maintaining the unified exception interface.

Why does aisuite raise LLMError when using streaming with some providers?

The abstract Provider class defines chat_completions_create_stream to raise LLMError by default. Concrete providers must override this method to support streaming; if they do not, the base implementation raises LLMError to signal that streaming is unavailable for that backend.

Can I catch provider-specific errors like RateLimitError directly in aisuite?

No, aisuite intentionally wraps all provider-specific exceptions into LLMError to maintain abstraction. You should catch LLMError and inspect err.__cause__ to handle provider-specific cases, ensuring your error handling logic remains compatible when switching between providers.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →