> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> Comprehensive guide to handling errors in the StateSet API

<Info>
  StateSet uses conventional HTTP response codes and provides detailed error messages to help you quickly identify and resolve issues.
</Info>

## 🚨 Error Response Format

All errors follow a consistent JSON structure:

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "The 'amount' parameter is required but was not provided",
    "param": "amount",
    "doc_url": "https://docs.stateset.com/errors/parameter_missing",
    "request_id": "req_1234567890abcdef"
  }
}
```

### Error Object Fields

| Field        | Type   | Description                                        |
| ------------ | ------ | -------------------------------------------------- |
| `type`       | string | The type of error returned                         |
| `code`       | string | A short string identifying the error               |
| `message`    | string | A human-readable message providing details         |
| `param`      | string | The parameter related to the error (if applicable) |
| `doc_url`    | string | Link to relevant documentation                     |
| `request_id` | string | Unique identifier for this request                 |

## 📊 HTTP Status Codes

<Tabs>
  <Tab title="2xx Success">
    | Code | Meaning    | Description                             |
    | ---- | ---------- | --------------------------------------- |
    | 200  | OK         | Request succeeded                       |
    | 201  | Created    | Resource successfully created           |
    | 202  | Accepted   | Request accepted for processing         |
    | 204  | No Content | Request succeeded with no response body |
  </Tab>

  <Tab title="4xx Client Errors">
    | Code | Meaning              | Description                             |
    | ---- | -------------------- | --------------------------------------- |
    | 400  | Bad Request          | Invalid request syntax or parameters    |
    | 401  | Unauthorized         | Missing or invalid authentication       |
    | 403  | Forbidden            | Valid auth but insufficient permissions |
    | 404  | Not Found            | Requested resource doesn't exist        |
    | 409  | Conflict             | Request conflicts with current state    |
    | 422  | Unprocessable Entity | Request understood but invalid          |
    | 429  | Too Many Requests    | Rate limit exceeded                     |
  </Tab>

  <Tab title="5xx Server Errors">
    | Code | Meaning               | Description                    |
    | ---- | --------------------- | ------------------------------ |
    | 500  | Internal Server Error | Unexpected server error        |
    | 502  | Bad Gateway           | Invalid response from upstream |
    | 503  | Service Unavailable   | Service temporarily offline    |
    | 504  | Gateway Timeout       | Upstream request timeout       |
  </Tab>
</Tabs>

## 🔍 Error Types

### Authentication Errors

Occur when API keys are missing, invalid, or lack permissions.

```json theme={null}
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The provided API key is invalid",
    "request_id": "req_abc123"
  }
}
```

<AccordionGroup>
  <Accordion title="Common Authentication Error Codes">
    * `api_key_missing` - No API key provided
    * `invalid_api_key` - API key is malformed or doesn't exist
    * `api_key_expired` - API key has expired
    * `api_key_revoked` - API key has been revoked
    * `insufficient_permissions` - API key lacks required permissions
  </Accordion>
</AccordionGroup>

### Invalid Request Errors

Occur when request parameters are invalid or missing.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "Amount must be a positive number",
    "param": "amount",
    "request_id": "req_def456"
  }
}
```

<AccordionGroup>
  <Accordion title="Common Invalid Request Error Codes">
    * `parameter_missing` - Required parameter not provided
    * `parameter_invalid` - Parameter value is invalid
    * `parameter_unknown` - Unknown parameter provided
    * `request_invalid` - Request body is malformed
    * `idempotency_key_in_use` - Idempotency key already used
  </Accordion>
</AccordionGroup>

### Rate Limit Errors

Occur when you exceed API rate limits.

```json theme={null}
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Please retry after 60 seconds",
    "request_id": "req_ghi789"
  }
}
```

Response headers include:

```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995200
Retry-After: 60
```

### API Errors

Occur due to problems on StateSet's servers.

```json theme={null}
{
  "error": {
    "type": "api_error",
    "code": "internal_server_error",
    "message": "An unexpected error occurred. Please try again",
    "request_id": "req_jkl012"
  }
}
```

## 💻 Error Handling Examples

<CodeGroup>
  ```javascript Node.js theme={null}
  const { StateSet } = require('@stateset/sdk');

  const stateset = new StateSet({
    apiKey: process.env.STATESET_API_KEY
  });

  async function makePayment(amount, recipient) {
    try {
      const payment = await stateset.payments.create({
        amount,
        recipient,
        currency: 'ssusd'
      });
      return payment;
    } catch (error) {
      // Handle different error types
      switch (error.type) {
        case 'authentication_error':
          console.error('Authentication failed:', error.message);
          // Refresh API key or prompt for authentication
          break;
          
        case 'invalid_request_error':
          console.error('Invalid request:', error.message);
          if (error.param) {
            console.error('Problem with parameter:', error.param);
          }
          break;
          
        case 'rate_limit_error':
          console.error('Rate limit hit, retrying after delay...');
          const retryAfter = error.headers?.['retry-after'] || 60;
          await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
          return makePayment(amount, recipient); // Retry
          
        case 'api_error':
          console.error('StateSet API error:', error.message);
          // Log to monitoring service
          break;
          
        default:
          console.error('Unknown error:', error);
      }
      
      throw error;
    }
  }
  ```

  ```python Python theme={null}
  from stateset import StateSet
  from stateset.error import (
      AuthenticationError,
      InvalidRequestError,
      RateLimitError,
      APIError
  )
  import time

  stateset = StateSet(api_key=os.getenv('STATESET_API_KEY'))

  def make_payment(amount, recipient):
      try:
          payment = stateset.Payment.create(
              amount=amount,
              recipient=recipient,
              currency='ssusd'
          )
          return payment
          
      except AuthenticationError as e:
          print(f"Authentication failed: {e.user_message}")
          # Handle authentication error
          raise
          
      except InvalidRequestError as e:
          print(f"Invalid request: {e.user_message}")
          if e.param:
              print(f"Problem with parameter: {e.param}")
          # Handle validation error
          raise
          
      except RateLimitError as e:
          print("Rate limit hit, retrying after delay...")
          retry_after = int(e.headers.get('retry-after', 60))
          time.sleep(retry_after)
          return make_payment(amount, recipient)  # Retry
          
      except APIError as e:
          print(f"StateSet API error: {e.user_message}")
          # Log to monitoring service
          raise
          
      except Exception as e:
          print(f"Unexpected error: {str(e)}")
          raise
  ```

  ```go Go theme={null}
  package main

  import (
      "fmt"
      "time"
      "github.com/stateset/stateset-go"
  )

  func makePayment(client *stateset.Client, amount int64, recipient string) (*stateset.Payment, error) {
      payment, err := client.Payments.Create(&stateset.PaymentParams{
          Amount:    stateset.Int64(amount),
          Recipient: stateset.String(recipient),
          Currency:  stateset.String("ssusd"),
      })
      
      if err != nil {
          // Type assert to StateSet error
          if statesetErr, ok := err.(*stateset.Error); ok {
              switch statesetErr.Type {
              case "authentication_error":
                  return nil, fmt.Errorf("auth failed: %s", statesetErr.Message)
                  
              case "invalid_request_error":
                  if statesetErr.Param != "" {
                      return nil, fmt.Errorf("invalid param %s: %s", 
                          statesetErr.Param, statesetErr.Message)
                  }
                  return nil, fmt.Errorf("invalid request: %s", statesetErr.Message)
                  
              case "rate_limit_error":
                  // Retry after delay
                  retryAfter := statesetErr.Headers.Get("Retry-After")
                  duration, _ := time.ParseDuration(retryAfter + "s")
                  time.Sleep(duration)
                  return makePayment(client, amount, recipient)
                  
              case "api_error":
                  return nil, fmt.Errorf("API error: %s", statesetErr.Message)
              }
          }
          
          return nil, err
      }
      
      return payment, nil
  }
  ```
</CodeGroup>

## 🔄 Retry Strategy

Implement exponential backoff with jitter for transient errors:

```javascript theme={null}
async function retryWithBackoff(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      // Don't retry client errors (except rate limits)
      if (error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429) {
        throw error;
      }
      
      if (i === maxRetries - 1) throw error;
      
      // Exponential backoff with jitter
      const delay = Math.min(1000 * Math.pow(2, i) + Math.random() * 1000, 10000);
      console.log(`Retry ${i + 1}/${maxRetries} after ${delay}ms`);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

// Usage
const payment = await retryWithBackoff(() => 
  stateset.payments.create({ amount: 100, recipient: 'stateset1abc...' })
);
```

## 🛡️ Idempotency

Prevent duplicate operations using idempotency keys:

```javascript theme={null}
const payment = await stateset.payments.create({
  amount: 100,
  recipient: 'stateset1abc...',
  idempotency_key: 'unique-operation-key-123'
});

// Safe to retry - will return the same result
const samePayment = await stateset.payments.create({
  amount: 100,
  recipient: 'stateset1abc...',
  idempotency_key: 'unique-operation-key-123'
});
```

## 📈 Common Error Scenarios

### Insufficient Funds

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "insufficient_funds",
    "message": "Account has insufficient funds for this transaction",
    "param": "amount",
    "available_balance": "50.00",
    "requested_amount": "100.00",
    "currency": "ssusd"
  }
}
```

### Invalid Address

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_address",
    "message": "The recipient address is not a valid StateSet address",
    "param": "recipient",
    "provided_value": "invalid-address"
  }
}
```

### Compliance Block

```json theme={null}
{
  "error": {
    "type": "compliance_error",
    "code": "transaction_blocked",
    "message": "This transaction cannot be processed due to compliance restrictions",
    "compliance_reason": "sanctions_screening",
    "request_id": "req_xyz789"
  }
}
```

## 🔍 Debugging Tips

### 1. Use Request IDs

Always log the `request_id` for support inquiries:

```javascript theme={null}
try {
  const result = await stateset.someMethod();
} catch (error) {
  console.error(`Request failed: ${error.request_id}`);
  // Include request_id in bug reports
}
```

### 2. Enable Debug Mode

Get detailed request/response logs:

```javascript theme={null}
const stateset = new StateSet({
  apiKey: process.env.STATESET_API_KEY,
  debug: true // Logs all requests/responses
});
```

### 3. Check Status Page

Monitor API health at [status.stateset.com](https://status.stateset.com)

### 4. Use Test Mode

Test error scenarios safely:

```javascript theme={null}
// Force specific errors in test mode
const payment = await stateset.payments.create({
  amount: 100,
  recipient: 'stateset1_test_insufficient_funds', // Special test address
  currency: 'ssusd'
});
```

## 📊 Error Monitoring

Set up proper error tracking:

```javascript theme={null}
// Example with Sentry
import * as Sentry from '@sentry/node';

async function trackError(error) {
  Sentry.captureException(error, {
    tags: {
      error_type: error.type,
      error_code: error.code,
      request_id: error.request_id
    },
    extra: {
      param: error.param,
      api_version: 'v1'
    }
  });
}
```

## 🆘 Getting Help

<CardGroup cols={2}>
  <Card title="Error Reference" icon="book" href="/errors/reference">
    Complete list of all error codes
  </Card>

  <Card title="Support Portal" icon="headset" href="https://support.stateset.com">
    Contact support with request IDs
  </Card>

  <Card title="Status Page" icon="signal" href="https://status.stateset.com">
    Check current API status
  </Card>

  <Card title="Discord Community" icon="discord" href="https://discord.gg/stateset">
    Get help from the community
  </Card>
</CardGroup>
