Skip to main content
Learn how to handle errors gracefully and build robust applications with the Gravix Layer SDK.

Common Error Types

The SDK provides specific exceptions for different scenarios:
from gravixlayer.types.exceptions import (
    GravixLayerError,                    # Base exception
    GravixLayerAuthenticationError,      # Invalid API key
    GravixLayerRateLimitError,          # Rate limit exceeded
    GravixLayerServerError,             # Server errors (5xx)
    GravixLayerBadRequestError,         # Bad request errors (4xx)
    GravixLayerConnectionError          # Connection errors
)

Basic Error Handling

Always wrap API calls in try-catch blocks:
from gravixlayer import GravixLayer
from gravixlayer.types.exceptions import GravixLayerError

client = GravixLayer()

try:
    response = client.chat.completions.create(
        model="meta-llama/llama-3.1-8b-instruct",
        messages=[{"role": "user", "content": "Hello"}]
    )
    print(response.choices[0].message.content)
except GravixLayerError as e:
    print(f"API Error: {e}")

Retry Logic with Backoff

Handle transient errors with exponential backoff:
import time
from gravixlayer import GravixLayer
from gravixlayer.types.exceptions import (
    GravixLayerRateLimitError,
    GravixLayerConnectionError,
    GravixLayerServerError
)

def make_request_with_retry(messages, max_retries=3):
    client = GravixLayer()
    
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model="meta-llama/llama-3.1-8b-instruct",
                messages=messages
            )
        
        except GravixLayerRateLimitError:
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff
                print(f"Rate limit hit. Retrying in {wait_time} seconds...")
                time.sleep(wait_time)
            else:
                print("Rate limit exceeded. Max retries reached.")
                raise
        
        except (GravixLayerConnectionError, GravixLayerServerError):
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt
                print(f"Connection/Server error. Retrying in {wait_time}s... (attempt {attempt + 1})")
                time.sleep(wait_time)
            else:
                print("Max retries reached.")
                raise

# Usage
try:
    response = make_request_with_retry([
        {"role": "user", "content": "Hello!"}
    ])
    print(response.choices[0].message.content)
except Exception as e:
    print(f"Failed after all retries: {e}")

Handling Specific Errors

Handle different error types with specific actions:
from gravixlayer import GravixLayer
from gravixlayer.types.exceptions import (
    GravixLayerAuthenticationError,
    GravixLayerRateLimitError,
    GravixLayerBadRequestError
)

client = GravixLayer()

try:
    response = client.chat.completions.create(
        model="meta-llama/llama-3.1-8b-instruct",
        messages=[{"role": "user", "content": "Hello"}]
    )
    print(response.choices[0].message.content)

except GravixLayerAuthenticationError:
    print("❌ Invalid API key. Please check your credentials.")

except GravixLayerRateLimitError as e:
    print(f"⏳ Rate limit exceeded. Try again later: {e}")

except GravixLayerBadRequestError as e:
    print(f"📝 Invalid request parameters: {e}")

except Exception as e:
    print(f"💥 Unexpected error: {e}")

Async Error Handling

Error handling works the same with async methods:
import asyncio
from gravixlayer import AsyncGravixLayer
from gravixlayer.types.exceptions import GravixLayerError

async def safe_async_request():
    client = AsyncGravixLayer()
    try:
        response = await client.chat.completions.create(
            model="meta-llama/llama-3.1-8b-instruct",
            messages=[{"role": "user", "content": "Hello"}]
        )
        return response.choices[0].message.content
    except GravixLayerError as e:
        print(f"Async API Error: {e}")
        return None

result = asyncio.run(safe_async_request())
if result:
    print(result)

Production-Ready Error Handler

A comprehensive error handler for production applications:
import logging
import time
from gravixlayer import GravixLayer
from gravixlayer.types.exceptions import (
    GravixLayerAuthenticationError,
    GravixLayerRateLimitError,
    GravixLayerBadRequestError,
    GravixLayerConnectionError,
    GravixLayerServerError,
    GravixLayerError
)

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class RobustClient:
    def __init__(self, max_retries=3, base_delay=1):
        self.client = GravixLayer()
        self.max_retries = max_retries
        self.base_delay = base_delay
    
    def chat_completion(self, messages, model="meta-llama/llama-3.1-8b-instruct"):
        """Make a chat completion request with robust error handling."""
        
        for attempt in range(self.max_retries):
            try:
                response = self.client.chat.completions.create(
                    model=model,
                    messages=messages
                )
                logger.info(f"✅ Request successful on attempt {attempt + 1}")
                return response
            
            except GravixLayerAuthenticationError as e:
                logger.error(f"❌ Authentication failed: {e}")
                raise  # Don't retry auth errors
            
            except GravixLayerBadRequestError as e:
                logger.error(f"📝 Invalid request: {e}")
                raise  # Don't retry validation errors
            
            except GravixLayerRateLimitError as e:
                if attempt < self.max_retries - 1:
                    delay = self.base_delay * (2 ** attempt)
                    logger.warning(f"⏳ Rate limited. Retrying in {delay}s: {e}")
                    time.sleep(delay)
                else:
                    logger.error(f"❌ Rate limit exceeded after {self.max_retries} attempts")
                    raise
            
            except (GravixLayerConnectionError, GravixLayerServerError) as e:
                if attempt < self.max_retries - 1:
                    delay = self.base_delay * (2 ** attempt)
                    logger.warning(f"⏱️ Connection/Server error. Retrying in {delay}s: {e}")
                    time.sleep(delay)
                else:
                    logger.error(f"❌ Error after {self.max_retries} attempts")
                    raise
            
            except GravixLayerError as e:
                logger.error(f"💥 API error: {e}")
                if attempt < self.max_retries - 1:
                    delay = self.base_delay * (attempt + 1)
                    logger.info(f"🔄 Retrying in {delay}s...")
                    time.sleep(delay)
                else:
                    raise

# Usage
client = RobustClient()

try:
    response = client.chat_completion([
        {"role": "user", "content": "Hello!"}
    ])
    print(response.choices[0].message.content)
except Exception as e:
    print(f"Request failed: {e}")

Best Practices

  1. Always use try-catch for API calls
  2. Implement exponential backoff for rate limits
  3. Log errors appropriately for debugging
  4. Don’t retry authentication errors - fix the API key instead
  5. Set reasonable timeouts to prevent hanging requests
  6. Handle specific error types differently based on your use case