> For the complete documentation index, see [llms.txt](https://docs.amigo.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amigo.ai/developer-guide/classic-api/sdks/sdk-error-handling.md).

# 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
    RateLimitError,       # 429 rate limit
)
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
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
} from '@amigo-ai/sdk'
```

{% 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,
    RateLimitError,
    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.organizations.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 RateLimitError as e:
        print(f"Rate limited: {e}")
        # Handle 429 rate limiting. The SDKs retry 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,
  AmigoError,
  AuthenticationError,
  NotFoundError,
  BadRequestError,
  ValidationError,
  ConflictError,
  NetworkError,
} 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 AuthenticationError) {
      console.log(`Authentication failed: ${error.message}`)
      // Handle invalid credentials. Check API keys.
      
    } else if (error instanceof NotFoundError) {
      console.log(`Resource not found: ${error.message}`)
      // Handle missing resources. Check IDs.
      
    } else if (error instanceof BadRequestError) {
      console.log(`Bad request: ${error.message}`)
      // Handle invalid request format
      
    } else if (error instanceof ValidationError) {
      console.log(`Validation failed: ${error.message}`)
      // Handle request validation errors
      
    } else if (error instanceof ConflictError) {
      console.log(`Conflict: ${error.message}`)
      // Handle resource conflicts (often recoverable)
      
    } else if (error instanceof NetworkError) {
      console.log(`Network error: ${error.message}`)
      // Handle connection issues. The SDKs retry automatically.
      
    } else if (error instanceof 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](/developer-guide/classic-api/core-api/conversations/conversations-interact.md).

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

```python
def handle_stream_errors():
    with AmigoClient() as client:
        try:
            events = client.conversations.create_conversation(
                request, CreateConversationParametersQuery(response_format="text")
            )
            
            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
%%{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**](/developer-guide/classic-api/core-api/conversations/conversations-interact.md)**.** Streaming and reliable handlers.
* [**Manage users**](/developer-guide/classic-api/core-api/users.md)**.** User management with error handling.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/developer-guide/classic-api/sdks/sdk-error-handling.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
