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

# Error Handling

> Error codes, recovery strategies, and automatic fund clawback

The Flashnet SDK provides a comprehensive error system with typed error codes, automatic fund recovery, and clear guidance on how to handle each type of failure.

## Error Codes

All Flashnet AMM Gateway errors follow the format `FSAG-XXXX` and are categorized by their numeric range:

| Range     | Category       | Description                             |
| --------- | -------------- | --------------------------------------- |
| 1000-1999 | Validation     | Request validation failures             |
| 2000-2999 | Security       | Authentication and authorization errors |
| 3000-3999 | Infrastructure | External service and network issues     |
| 4000-4999 | Business       | AMM logic and pool state errors         |
| 5000-5999 | System         | Internal service errors                 |

## Recovery Strategies

Each error has an associated recovery strategy that tells you how to handle fund recovery:

| Strategy               | Description                             | Action Required                          |
| ---------------------- | --------------------------------------- | ---------------------------------------- |
| `clawback_required`    | Funds are at risk and must be recovered | Clawback will be attempted automatically |
| `clawback_recommended` | Uncertain state, recovery recommended   | Clawback will be attempted automatically |
| `auto_refund`          | Funds return automatically              | No action needed                         |
| `none`                 | No funds at risk                        | No action needed                         |

## Automatic Clawback

<Info>
  The SDK automatically attempts to clawback your funds when an operation fails with a clawbackable error. You don't need to manually handle fund recovery in most cases.
</Info>

When you execute operations like `executeSwap`, `executeRouteSwap`, `addLiquidity`, or `createSingleSidedPool`, the SDK:

1. Sends your funds to the pool
2. Executes the operation
3. **If the operation fails with a clawbackable error**, automatically attempts to recover your funds
4. Returns a `FlashnetError` with details about what happened and the recovery status

### Example: Handling Auto-Clawback

```typescript theme={null}
import { isFlashnetError } from '@flashnet/sdk';

try {
  const swap = await client.executeSwap({
    poolId: "pool-id",
    assetInAddress: "bitcoin-pubkey",
    assetOutAddress: "usdb-pubkey",
    amountIn: "100000000",
    minAmountOut: "99000000",
    maxSlippageBps: 100,
  });
  
  console.log('Swap successful:', swap.amountOut);
} catch (error) {
  if (isFlashnetError(error)) {
    console.log('Error code:', error.errorCode);
    console.log('Category:', error.category);
    console.log('User message:', error.userMessage);
    
    // Check if auto-clawback was attempted
    if (error.wasClawbackAttempted()) {
      const summary = error.clawbackSummary!;
      
      if (error.wereAllTransfersRecovered()) {
        console.log('✅ All funds recovered automatically!');
      } else if (error.werePartialTransfersRecovered()) {
        console.log(`⚠️ Partial recovery: ${summary.successCount}/${summary.totalTransfers}`);
        console.log('Unrecovered transfers:', summary.unrecoveredTransferIds);
      } else {
        console.log('❌ Fund recovery failed');
        console.log('At-risk transfers:', error.transferIds);
      }
    }
    
    // Check specific error types
    if (error.isSlippageError()) {
      console.log('Price moved too much - funds auto-refunded');
    } else if (error.isInsufficientLiquidityError()) {
      console.log('Pool lacks liquidity - funds auto-refunded');
    }
  }
}
```

## Complete Error Code Reference

### Validation Errors (1000-1999)

These errors indicate invalid request parameters. Recovery: **Clawback Required**

| Code      | HTTP | Summary                           | Retryable |
| --------- | ---- | --------------------------------- | --------- |
| FSAG-1000 | 400  | Validation failed                 | No        |
| FSAG-1001 | 400  | Required field missing            | No        |
| FSAG-1002 | 400  | Invalid field format              | No        |
| FSAG-1003 | 400  | Value out of range                | No        |
| FSAG-1004 | 409  | Duplicate value for unique entity | No        |

### Security Errors (2000-2999)

Authentication and authorization failures. Recovery: **Clawback Required** (except auth token errors)

| Code      | HTTP | Summary                             | Retryable |
| --------- | ---- | ----------------------------------- | --------- |
| FSAG-2001 | 403  | Signature verification failed       | No        |
| FSAG-2002 | 403  | Token identity mismatch             | No        |
| FSAG-2003 | 401  | Authorization token missing         | Yes       |
| FSAG-2004 | 401  | Authorization token invalid/expired | Yes       |
| FSAG-2005 | 403  | Nonce verification failed           | No        |
| FSAG-2101 | 400  | Public key invalid                  | No        |

### Infrastructure Errors (3000-3999)

External service and network issues. Recovery: **Clawback Recommended**

| Code        | HTTP | Summary               | Retryable |
| ----------- | ---- | --------------------- | --------- |
| FSAG-3001   | 503  | Internal server error | Yes       |
| FSAG-3002   | 500  | Internal server error | Yes       |
| FSAG-3101   | 500  | Internal server error | Yes       |
| FSAG-3201   | 503  | Internal server error | Yes       |
| FSAG-3201T1 | 503  | Internal server error | Yes       |
| FSAG-3201T2 | 503  | Internal server error | Yes       |
| FSAG-3202   | 503  | Internal server error | Yes       |
| FSAG-3301   | 500  | Internal server error | Yes       |
| FSAG-3302   | 503  | Internal server error | Yes       |
| FSAG-3401   | 500  | Internal server error | Yes       |
| FSAG-3402   | 500  | Internal server error | Yes       |

### Business Errors (4000-4999)

AMM logic and pool state errors. Recovery: **Auto Refund** (funds return automatically)

| Code      | HTTP | Summary                                | Retryable |
| --------- | ---- | -------------------------------------- | --------- |
| FSAG-4001 | 404  | Pool not found                         | No        |
| FSAG-4002 | 404  | Host not found                         | No        |
| FSAG-4101 | 404  | Auth session not found                 | Yes       |
| FSAG-4102 | 400  | Incorrect authentication flow          | Yes       |
| FSAG-4201 | 400  | Insufficient liquidity/reserves        | Yes       |
| FSAG-4202 | 400  | Slippage exceeded limit                | Yes       |
| FSAG-4203 | 409  | Operation not allowed in current phase | Yes       |
| FSAG-4204 | 400  | Insufficient LP token balance          | No        |
| FSAG-4301 | 400  | Invalid fee configuration              | No        |
| FSAG-4401 | 409  | Spark transfer ID already used         | No        |

### System Errors (5000-5999)

Internal service errors. Recovery: **Clawback Required**

| Code      | HTTP | Summary                         | Retryable |
| --------- | ---- | ------------------------------- | --------- |
| FSAG-5001 | 500  | Failed to generate unique ID    | Yes       |
| FSAG-5002 | 501  | Feature not implemented         | No        |
| FSAG-5003 | 500  | Internal state inconsistent     | No        |
| FSAG-5004 | 500  | Invalid configuration parameter | No        |
| FSAG-5100 | 500  | Unexpected panic                | No        |

## FlashnetError Properties

The `FlashnetError` class provides rich error information:

```typescript theme={null}
interface FlashnetError extends Error {
  // Core properties
  errorCode: string;           // e.g., "FSAG-4202"
  category: string;            // "Validation" | "Security" | "Infrastructure" | "Business" | "System"
  recovery: string;            // "clawback_required" | "clawback_recommended" | "auto_refund" | "none"
  httpStatus: number;          // HTTP status code
  requestId: string;           // Unique request ID for debugging
  
  // User-facing
  userMessage: string;         // Human-readable explanation
  actionHint: string;          // Suggested action
  isRetryable: boolean;        // Whether retry makes sense
  
  // Clawback info
  transferIds: string[];       // Unrecovered transfer IDs
  lpIdentityPublicKey?: string; // Pool ID for clawback
  clawbackSummary?: {          // Auto-clawback results
    attempted: boolean;
    totalTransfers: number;
    successCount: number;
    failureCount: number;
    recoveredTransferIds: string[];
    unrecoveredTransferIds: string[];
    results: ClawbackAttemptResult[];
  };
}
```

## FlashnetError Methods

```typescript theme={null}
// Recovery status
error.isClawbackRequired();        // True if clawback is mandatory
error.isClawbackRecommended();     // True if clawback is advised
error.shouldClawback();            // True if either required or recommended
error.willAutoRefund();            // True if funds return automatically
error.hasTransfersAtRisk();        // True if unrecovered transfers exist

// Clawback status
error.wasClawbackAttempted();      // True if auto-clawback ran
error.wereAllTransfersRecovered(); // True if all funds recovered
error.werePartialTransfersRecovered(); // True if some but not all recovered
error.getRecoveredTransferCount(); // Number of recovered transfers
error.getRecoveredTransferIds();   // IDs of recovered transfers
error.getUnrecoveredTransferIds(); // IDs still at risk

// Error type checks
error.isValidationError();
error.isSecurityError();
error.isInfrastructureError();
error.isBusinessError();
error.isSystemError();

// Specific error checks
error.isSlippageError();           // FSAG-4202
error.isInsufficientLiquidityError(); // FSAG-4201
error.isAuthError();               // FSAG-2003 or FSAG-2004
error.isPoolNotFoundError();       // FSAG-4001
error.isTransferAlreadyUsedError(); // FSAG-4401

// Formatting
error.getUserFriendlyMessage();    // Full user-facing message
error.toLogString();               // Formatted for logging
error.toJSON();                    // Serializable object
```

## Best Practices

### 1. Always Use Type Guards

```typescript theme={null}
import { isFlashnetError, FlashnetError } from '@flashnet/sdk';

try {
  await client.executeSwap({ /* ... */ });
} catch (error) {
  if (isFlashnetError(error)) {
    // Full typed access to error properties
    console.log(error.errorCode, error.userMessage);
  } else {
    // Generic error handling
    console.error('Unknown error:', error);
  }
}
```

### 2. Handle Business Errors Gracefully

Business errors (4000-4999) indicate conditions like slippage or insufficient liquidity. These are **auto-refunded** and often retryable:

```typescript theme={null}
if (error.isBusinessError()) {
  if (error.isSlippageError()) {
    // Suggest user increase slippage tolerance
    showMessage('Price moved. Try increasing slippage tolerance.');
  } else if (error.isInsufficientLiquidityError()) {
    // Suggest smaller trade or different pool
    showMessage('Not enough liquidity. Try a smaller amount.');
  }
  
  // Funds are automatically returned
  if (error.willAutoRefund()) {
    showMessage('Your funds will be returned automatically.');
  }
}
```

### 3. Log Request IDs for Debugging

```typescript theme={null}
catch (error) {
  if (isFlashnetError(error)) {
    console.error(`[${error.requestId}] ${error.toLogString()}`);
    // Report to your error tracking service
    reportError({
      requestId: error.requestId,
      errorCode: error.errorCode,
      ...error.toJSON()
    });
  }
}
```

### 4. Implement Retry Logic for Retryable Errors

```typescript theme={null}
async function executeWithRetry(fn: () => Promise<any>, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (isFlashnetError(error) && error.isRetryable && attempt < maxRetries) {
        const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
        console.log(`Retrying in ${delay}ms... (attempt ${attempt}/${maxRetries})`);
        await new Promise(r => setTimeout(r, delay));
        continue;
      }
      throw error;
    }
  }
}
```

## Next Steps

* Learn about the [Clawback Monitor](/products/flashnet-amm/advanced#clawback-monitor) for background recovery
* See [Advanced Topics](/products/flashnet-amm/advanced) for manual clawback and recovery tools
