# Error Handling

This guide covers error handling when using the Amigo SDK in Python or TypeScript. Both SDKs include built-in retry logic for transient network failures and provide full error handling for all API operations.

## Error Types

Both SDKs provide typed error handling for different types of failures:

{% tabs %}
{% tab title="Python" %}

```python
from amigo_sdk.errors import (
    AmigoError,           # Base error class
    AuthenticationError,   # Invalid credentials
    NotFoundError,        # Resource not found  
    BadRequestError,      # Invalid request
    ValidationError,      # Request validation failed
    ConflictError,        # Resource conflict
    NetworkError,         # Network/connection issues
)
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
import { errors } from '@amigo-ai/sdk'

// Available error types:
errors.AmigoError           // Base error class
errors.AuthenticationError  // Invalid credentials
errors.NotFoundError       // Resource not found
errors.BadRequestError     // Invalid request
errors.ValidationError     // Request validation failed
errors.ConflictError       // Resource conflict  
errors.NetworkError        // Network/connection issues
```

{% endtab %}
{% endtabs %}

## Basic Error Handling

{% tabs %}
{% tab title="Python" %}

```python
from amigo_sdk import AmigoClient
from amigo_sdk.errors import (
    AuthenticationError,
    NotFoundError,
    BadRequestError,
    ValidationError,
    ConflictError,
    NetworkError,
    AmigoError
)

def handle_errors_example():
    try:
        with AmigoClient(
            api_key="your-api-key",
            api_key_id="your-api-key-id",
            user_id="your-user-id",
            organization_id="your-org-id"
        ) as client:
            # Your API calls here
            org = client.organization.get()
            print(f"Organization: {org.name}")
            
    except AuthenticationError as e:
        print(f"Authentication failed: {e}")
        # Handle invalid credentials - check API keys
        
    except NotFoundError as e:
        print(f"Resource not found: {e}")
        # Handle missing resources - check IDs
        
    except BadRequestError as e:
        print(f"Bad request: {e}")
        # Handle invalid request format
        
    except ValidationError as e:
        print(f"Validation failed: {e}")
        # Handle request validation errors
        
    except ConflictError as e:
        print(f"Conflict: {e}")
        # Handle resource conflicts (often recoverable)
        
    except NetworkError as e:
        print(f"Network error: {e}")
        # Handle connection issues - SDKs handle retries automatically
        
    except AmigoError as e:
        print(f"Amigo API error: {e}")
        # Handle any other Amigo-specific errors
        
    except Exception as e:
        print(f"Unexpected error: {e}")
        # Handle unexpected errors
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
import { AmigoClient, errors } from '@amigo-ai/sdk'

async function handleErrorsExample(): Promise<void> {
  const client = new AmigoClient({
    apiKey: 'your-api-key',
    apiKeyId: 'your-api-key-id',
    userId: 'your-user-id',
    orgId: 'your-org-id'
  })

  try {
    // Your API calls here
    const org = await client.organizations.getOrganization()
    console.log(`Organization: ${org.name}`)
    
  } catch (error) {
    if (error instanceof errors.AuthenticationError) {
      console.log(`Authentication failed: ${error.message}`)
      // Handle invalid credentials - check API keys
      
    } else if (error instanceof errors.NotFoundError) {
      console.log(`Resource not found: ${error.message}`)
      // Handle missing resources - check IDs
      
    } else if (error instanceof errors.BadRequestError) {
      console.log(`Bad request: ${error.message}`)
      // Handle invalid request format
      
    } else if (error instanceof errors.ValidationError) {
      console.log(`Validation failed: ${error.message}`)
      // Handle request validation errors
      
    } else if (error instanceof errors.ConflictError) {
      console.log(`Conflict: ${error.message}`)
      // Handle resource conflicts (often recoverable)
      
    } else if (error instanceof errors.NetworkError) {
      console.log(`Network error: ${error.message}`)
      // Handle connection issues - SDKs handle retries automatically
      
    } else if (error instanceof errors.AmigoError) {
      console.log(`Amigo API error: ${error.message}`)
      // Handle any other Amigo-specific errors
      
    } else {
      console.log(`Unexpected error:`, error)
      // Handle unexpected errors
    }
  }
}
```

{% endtab %}
{% endtabs %}

## Stream Error Handling

When processing streaming responses, handle errors within the stream (see also [Conversations: Interact](https://docs.amigo.ai/developer-guide/classic-api/core-api/conversations/conversations-interact)):

{% tabs %}
{% tab title="Python" %}

```python
def handle_stream_errors():
    with AmigoClient() as client:
        try:
            events = client.conversation.create_conversation(request)
            
            for event in events:
                event_data = event.model_dump(mode="json")
                
                # Check for error events in the stream
                if event_data.get("type") == "error":
                    error_message = event_data.get("message", "Unknown error")
                    print(f"Stream error: {error_message}")
                    break
                    
                # Process normal events
                print(f"Event: {event_data.get('type')}")
                
        except Exception as e:
            print(f"Stream processing error: {e}")
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
async function handleStreamErrors(): Promise<void> {
  const client = new AmigoClient({...config})
  
  try {
    const events = await client.conversations.createConversation({...})
    
    for await (const event of events) {
      // Check for error events in the stream
      if (event.type === 'error') {
        console.log(`Stream error: ${event.message || 'Unknown error'}`)
        break
      }
      
      // Process normal events
      console.log(`Event: ${event.type}`)
    }
    
  } catch (error) {
    console.log(`Stream processing error:`, error)
  }
}
```

{% endtab %}
{% endtabs %}

## Built-in Retry Logic

Both SDKs include automatic retry logic for transient failures:

| Error Type              | Retry Strategy                    |
| ----------------------- | --------------------------------- |
| **Network errors**      | Automatic exponential backoff     |
| **Rate limiting**       | Automatic retry with proper delay |
| **Server errors (5xx)** | Intelligent retry with backoff    |

{% hint style="info" %}
**Automatic Retries** You don't need to implement retry logic manually. The SDKs handle retries automatically for appropriate error types.
{% endhint %}

### Retry Flow Diagram

{% @mermaid/diagram content="%%{init: {"flowchart": {"useMaxWidth": true, "nodeSpacing": 30, "rankSpacing": 40}, "theme": "base", "themeVariables": {"primaryColor": "#D4E2E7", "primaryTextColor": "#100F0F", "primaryBorderColor": "#083241", "lineColor": "#575452", "textColor": "#100F0F", "clusterBkg": "#F1EAE7", "clusterBorder": "#D7D2D0"}}}%%
flowchart TB
Start\[API Request] --> Try\[Execute Request]
Try --> Check{Success?}

```
Check -->|200 OK| Success[Return Response]
Check -->|Network Error| Retry{Retry Count < Max?}
Check -->|5xx Server Error| Retry
Check -->|429 Rate Limit| Retry
Check -->|4xx Client Error| Fail[Throw Error]

Retry -->|Yes| Wait[Exponential Backoff]
Wait --> Try
Retry -->|No| Fail

style Success fill:#DDE3DB,stroke:#2c3827,color:#100F0F,stroke-width:2px
style Fail fill:#F0DDD9,stroke:#AA412A,color:#100F0F,stroke-width:2px
style Wait fill:#F0DDD9,stroke:#AA412A,color:#100F0F,stroke-width:2px
style Try fill:#D4E2E7,stroke:#083241,color:#100F0F,stroke-width:2px" %}
```

## Best Practices

1. **Handle specific error types** - Don't just catch generic exceptions
2. **Log errors with context** - Include relevant IDs and operation details
3. **Check for stream error events** - Monitor the `error` event type in streams
4. **Trust built-in retries** - Let the SDK handle transient failures automatically
5. **Graceful degradation** - Provide fallback behavior when possible
6. **Monitor error patterns** - Track error rates and types in production

## Next Steps

With proper error handling in place, you're ready to:

* [**Work with conversations**](https://docs.amigo.ai/developer-guide/classic-api/core-api/conversations/conversations-interact) - Streaming and reliable handlers
* [**Manage users**](https://docs.amigo.ai/developer-guide/classic-api/core-api/users) - User management with error handling
