Skip to main content

Overview

The Google Gen AI SDK provides comprehensive error handling through the APIError class and its subclasses. You can catch specific error types, inspect error details, and configure automatic retry behavior.

APIError Class

All API errors inherit from the base APIError class, which provides access to error details:
from google import genai
from google.genai import errors

client = genai.Client(api_key='GEMINI_API_KEY')

try:
    response = client.models.generate_content(
        model="invalid-model-name",
        contents="What is your name?",
    )
except errors.APIError as e:
    print(f"Error code: {e.code}")        # HTTP status code (e.g., 404)
    print(f"Error status: {e.status}")    # Status string (e.g., 'NOT_FOUND')
    print(f"Error message: {e.message}")  # Human-readable error message
    print(f"Error details: {e.details}")  # Full error response

Error Types

ClientError (4xx)

Raised when the request is invalid due to client-side issues:
from google.genai import errors

try:
    response = client.models.generate_content(
        model="gemini-2.0-flash-exp",
        contents="",  # Empty content
    )
except errors.ClientError as e:
    if e.code == 400:
        print("Bad request: Invalid input parameters")
        print(f"Message: {e.message}")
    elif e.code == 401:
        print("Unauthorized: Invalid or missing API key")
    elif e.code == 403:
        print("Forbidden: Insufficient permissions")
    elif e.code == 404:
        print("Not found: Model or resource doesn't exist")
    elif e.code == 429:
        print("Rate limit exceeded: Too many requests")

ServerError (5xx)

Raised when the API experiences internal server issues:
from google.genai import errors

try:
    response = client.models.generate_content(
        model="gemini-2.0-flash-exp",
        contents="Generate a story",
    )
except errors.ServerError as e:
    if e.code == 500:
        print("Internal server error: Try again later")
    elif e.code == 503:
        print("Service unavailable: API is temporarily down")
    elif e.code == 504:
        print("Gateway timeout: Request took too long")
    
    # Log error details for debugging
    print(f"Full error: {e.details}")

Other Error Types

The SDK also defines these error types for specific situations:
from google.genai import errors

# Function calling errors
try:
    # Function call with invalid arguments
    pass
except errors.FunctionInvocationError as e:
    print(f"Function invocation failed: {e}")

except errors.UnknownFunctionCallArgumentError as e:
    print(f"Invalid function argument: {e}")

except errors.UnsupportedFunctionError as e:
    print(f"Function not supported: {e}")

# Response parsing errors
except errors.UnknownApiResponseError as e:
    print(f"Cannot parse API response: {e}")

Error Handling Strategies

Basic Try-Catch

from google import genai
from google.genai import errors

client = genai.Client(api_key='GEMINI_API_KEY')

try:
    response = client.models.generate_content(
        model='gemini-2.0-flash-exp',
        contents='Write a poem'
    )
    print(response.text)
except errors.APIError as e:
    print(f"API error occurred: {e}")

Granular Error Handling

from google import genai
from google.genai import errors

client = genai.Client(api_key='GEMINI_API_KEY')

try:
    response = client.models.generate_content(
        model='gemini-2.0-flash-exp',
        contents='Explain quantum computing'
    )
    print(response.text)

except errors.ClientError as e:
    if e.code == 400:
        print("Invalid request parameters. Please check your input.")
    elif e.code == 401:
        print("Authentication failed. Check your API key.")
    elif e.code == 429:
        print("Rate limit exceeded. Please wait before retrying.")
    else:
        print(f"Client error: {e.message}")

except errors.ServerError as e:
    print(f"Server error: {e.message}. Please try again later.")

except errors.APIError as e:
    print(f"Unexpected API error: {e}")

Async Error Handling

import asyncio
from google import genai
from google.genai import errors

client = genai.Client(api_key='GEMINI_API_KEY')

async def generate_with_error_handling():
    try:
        async for chunk in await client.aio.models.generate_content_stream(
            model='gemini-2.0-flash-exp',
            contents='Tell me a story'
        ):
            print(chunk.text, end='')
    
    except errors.ClientError as e:
        print(f"\nClient error: {e.message}")
    
    except errors.ServerError as e:
        print(f"\nServer error: {e.message}")
    
    except Exception as e:
        print(f"\nUnexpected error: {e}")

asyncio.run(generate_with_error_handling())

Retry Configuration

Configure automatic retry behavior for transient errors:

Basic Retry Configuration

from google import genai
from google.genai import types

client = genai.Client(
    api_key='GEMINI_API_KEY',
    http_options=types.HttpOptions(
        retry_options=types.HttpRetryOptions(
            attempts=5,              # Maximum 5 attempts (including original)
            initial_delay=1.0,       # 1 second initial delay
            max_delay=60.0,          # Maximum 60 seconds between retries
            exp_base=2.0,            # Exponential backoff multiplier
            jitter=1.0               # Randomness factor
        )
    )
)

Custom Retryable Status Codes

Specify which HTTP status codes should trigger retries:
from google import genai
from google.genai import types

client = genai.Client(
    api_key='GEMINI_API_KEY',
    http_options=types.HttpOptions(
        retry_options=types.HttpRetryOptions(
            attempts=3,
            initial_delay=2.0,
            http_status_codes=[408, 429, 500, 502, 503, 504]  # Retry on these codes
        )
    )
)

Disable Retries

from google import genai
from google.genai import types

client = genai.Client(
    api_key='GEMINI_API_KEY',
    http_options=types.HttpOptions(
        retry_options=types.HttpRetryOptions(attempts=1)  # No retries
    )
)

Per-Request Retry Configuration

Override retry settings for individual requests:
from google import genai
from google.genai import types

client = genai.Client(api_key='GEMINI_API_KEY')

response = client.models.generate_content(
    model='gemini-2.0-flash-exp',
    contents='Generate content',
    config=types.GenerateContentConfig(
        http_options=types.HttpOptions(
            retry_options=types.HttpRetryOptions(
                attempts=10,         # More aggressive retry for this request
                initial_delay=0.5,
                max_delay=120.0
            )
        )
    )
)

Retry Logic Details

The SDK uses exponential backoff with jitter for retries:
delay = min(
    initial_delay * (exp_base ** (attempt - 1)) * (1 + random.uniform(-jitter, jitter)),
    max_delay
)

Example Retry Delays

With default settings (initial_delay=1.0, exp_base=2.0, max_delay=60.0, jitter=1.0):
  • Attempt 1: 0-2 seconds (1.0 * 2^0 * random)
  • Attempt 2: 0-4 seconds (1.0 * 2^1 * random)
  • Attempt 3: 0-8 seconds (1.0 * 2^2 * random)
  • Attempt 4: 0-16 seconds (1.0 * 2^3 * random)
  • Attempt 5: 0-32 seconds (1.0 * 2^4 * random)

Complete Error Handling Example

import time
from google import genai
from google.genai import types, errors

def generate_content_with_fallback(prompt: str, max_retries: int = 3):
    """Generate content with comprehensive error handling and fallback."""
    
    client = genai.Client(
        api_key='GEMINI_API_KEY',
        http_options=types.HttpOptions(
            timeout=60000,  # 60 second timeout
            retry_options=types.HttpRetryOptions(
                attempts=3,
                initial_delay=1.0,
                max_delay=30.0,
                http_status_codes=[408, 429, 500, 502, 503, 504]
            )
        )
    )
    
    models = ['gemini-2.0-flash-exp', 'gemini-1.5-flash', 'gemini-1.5-pro']
    
    for model in models:
        for attempt in range(max_retries):
            try:
                response = client.models.generate_content(
                    model=model,
                    contents=prompt
                )
                return response.text
            
            except errors.ClientError as e:
                if e.code == 400:
                    print(f"Bad request for {model}: {e.message}")
                    break  # Don't retry, try next model
                elif e.code == 401:
                    raise ValueError("Invalid API key") from e
                elif e.code == 404:
                    print(f"Model {model} not found")
                    break  # Try next model
                elif e.code == 429:
                    wait_time = 2 ** attempt
                    print(f"Rate limited. Waiting {wait_time}s...")
                    time.sleep(wait_time)
                    continue
                else:
                    print(f"Client error: {e.message}")
                    break
            
            except errors.ServerError as e:
                print(f"Server error on attempt {attempt + 1}: {e.message}")
                if attempt < max_retries - 1:
                    time.sleep(2 ** attempt)
                    continue
                else:
                    break  # Try next model
            
            except Exception as e:
                print(f"Unexpected error: {e}")
                break
    
    raise RuntimeError("All models and retries exhausted")

# Usage
try:
    result = generate_content_with_fallback("Write a haiku about coding")
    print(result)
except Exception as e:
    print(f"Failed to generate content: {e}")

Best Practices

  1. Catch Specific Errors: Use ClientError and ServerError for different handling strategies
  2. Inspect Error Details: Check code, status, and message for detailed error information
  3. Configure Retries: Set appropriate retry behavior for your use case
  4. Log Error Details: Store error.details for debugging and monitoring
  5. Implement Fallbacks: Have backup models or strategies when primary requests fail
  6. Handle Rate Limits: Implement exponential backoff for 429 errors
  7. Monitor Errors: Track error rates and types to identify issues early

Build docs developers (and LLMs) love