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

# 错误处理

> 处理 Composer 特定错误和失败模式。

Composer 使用标准的 LI.FI API 错误格式，但有一些特定于 Composer 的错误和考虑因素。

***

## Composer 特定错误

| 错误代码                        | 描述            | 常见原因                        | 解决方案                       |
| --------------------------- | ------------- | --------------------------- | -------------------------- |
| `NO_POSSIBLE_ROUTE`         | 没有找到路径        | `toToken` 不是支持的金库代币         | 验证 `toToken` 地址是否在支持的协议列表中 |
| `COMPOSER_EXECUTION_FAILED` | Composer 执行失败 | 协议特定问题（如金库已满）               | 检查协议状态，稍后重试                |
| `INSUFFICIENT_LIQUIDITY`    | 流动性不足         | 目标协议流动性不足                   | 尝试较小金额或稍后重试                |
| `TRANSACTION_FAILED`        | 模拟失败          | 执行前模拟失败                     | 检查 gas 限制、协议状态             |
| `UNSUPPORTED_TOKEN`         | 不支持的代币        | `toToken` 不是支持的 Composer 代币 | 使用支持的协议代币                  |

***

## 常见失败模式

### 1. 协议级别失败

这些失败发生在目标协议层面：

* **金库容量限制**：金库已达到最大容量
* **协议暂停**：目标协议临时暂停
* **代币黑名单**：特定代币被协议阻止

**解决方案：**

```ts theme={"system"}
try {
  const executedRoute = await executeRoute(route);
} catch (error) {
  if (error.code === 'COMPOSER_EXECUTION_FAILED') {
    console.error('协议级别失败，检查协议状态');
    // 提示用户检查协议应用
  }
}
```

### 2. 跨链失败

跨链 Composer 流程的特定失败：

* **跨链桥失败**：跨链桥临时不可用
* **中间代币问题**：跨链代币在目标链不可用
* **Gas 不足**：目标链 gas 费用变化

**解决方案：**

```ts theme={"system"}
const trackCrossChainStatus = async (txHash: string, fromChain: number, toChain: number) => {
  const status = await getStatus(txHash, fromChain, toChain);
  
  if (status.status === 'FAILED' && status.substatus?.includes('bridge')) {
    console.error('跨链失败，可能需要重试');
    // 提示用户重试或使用不同跨链桥
  }
};
```

### 3. 执行前模拟失败

模拟在链上执行前失败：

* **Gas 估算错误**：交易需要比预期更多的 gas
* **状态变化**：模拟和执行之间状态发生变化
* **Slippage 过高**：价格变化超出可接受范围

**解决方案：**

```ts theme={"system"}
const quote = await getQuote({
  // ... 其他参数
  options: {
    slippage: 0.01, // 增加 slippage 容忍度
    gasLimit: 'auto', // 自动 gas 限制
  },
});
```

***

## 错误处理最佳实践

### 1. 预检查

在执行前验证条件：

```ts theme={"system"}
const preCheck = async (toToken: string, amount: string) => {
  // 检查代币是否受支持
  const supportedProtocols = await getSupportedProtocols();
  const isSupported = supportedProtocols.some(protocol => 
    protocol.tokens.includes(toToken)
  );
  
  if (!isSupported) {
    throw new Error('代币不受 Composer 支持');
  }
  
  // 检查最小/最大金额
  const limits = await getProtocolLimits(toToken);
  if (BigInt(amount) < limits.minDeposit) {
    throw new Error('金额低于最小存款要求');
  }
};
```

### 2. 重试逻辑

为临时失败实现重试：

```ts theme={"system"}
const executeWithRetry = async (route: Route, maxRetries = 3) => {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await executeRoute(route);
    } catch (error) {
      if (error.code === 'INSUFFICIENT_LIQUIDITY' && attempt < maxRetries) {
        console.log(`流动性不足，重试 ${attempt}/${maxRetries}`);
        await new Promise(resolve => setTimeout(resolve, 2000)); // 等待 2 秒
        continue;
      }
      throw error; // 重新抛出不可重试的错误
    }
  }
};
```

### 3. 用户友好的错误消息

将技术错误转换为用户友好的消息：

```ts theme={"system"}
const getErrorMessage = (error: any) => {
  switch (error.code) {
    case 'NO_POSSIBLE_ROUTE':
      return '无法找到路径。请检查目标代币是否为支持的金库代币。';
    case 'COMPOSER_EXECUTION_FAILED':
      return '协议执行失败。请检查协议状态或稍后重试。';
    case 'INSUFFICIENT_LIQUIDITY':
      return '流动性不足。请尝试较小金额或稍后重试。';
    case 'TRANSACTION_FAILED':
      return '交易失败。请检查您的余额和网络状态。';
    default:
      return '发生未知错误。请稍后重试。';
  }
};
```

***

## 监控和日志

### 1. 错误跟踪

```ts theme={"system"}
const executeWithErrorTracking = async (route: Route) => {
  try {
    return await executeRoute(route);
  } catch (error) {
    // 记录错误以供分析
    console.error('Composer 执行失败:', {
      error: error.message,
      code: error.code,
      route: route.id,
      timestamp: new Date().toISOString(),
    });
    
    // 发送到错误跟踪服务
    if (typeof window !== 'undefined') {
      window.analytics?.track('composer_error', {
        error_code: error.code,
        error_message: error.message,
        route_id: route.id,
      });
    }
    
    throw error;
  }
};
```

### 2. 性能监控

```ts theme={"system"}
const executeWithMetrics = async (route: Route) => {
  const startTime = Date.now();
  
  try {
    const result = await executeRoute(route);
    
    // 记录成功指标
    const duration = Date.now() - startTime;
    console.log('Composer 执行成功:', {
      duration,
      route_id: route.id,
      steps: route.steps.length,
    });
    
    return result;
  } catch (error) {
    // 记录失败指标
    const duration = Date.now() - startTime;
    console.error('Composer 执行失败:', {
      duration,
      error: error.code,
      route_id: route.id,
    });
    
    throw error;
  }
};
```

***

## 测试错误场景

### 1. 单元测试

```ts theme={"system"}
describe('Composer 错误处理', () => {
  it('应该处理不支持的代币', async () => {
    await expect(
      getQuote({
        toToken: 'UNSUPPORTED_TOKEN_ADDRESS',
        // ... 其他参数
      })
    ).rejects.toThrow('NO_POSSIBLE_ROUTE');
  });
  
  it('应该处理流动性不足', async () => {
    await expect(
      getQuote({
        fromAmount: '999999999999999999999', // 极大金额
        // ... 其他参数
      })
    ).rejects.toThrow('INSUFFICIENT_LIQUIDITY');
  });
});
```

### 2. 集成测试

```ts theme={"system"}
describe('Composer 集成错误处理', () => {
  it('应该优雅地处理跨链失败', async () => {
    const route = await getCrossChainRoute();
    
    // 模拟跨链失败
    jest.spyOn(bridgeService, 'execute').mockRejectedValue(
      new Error('BRIDGE_UNAVAILABLE')
    );
    
    await expect(executeRoute(route)).rejects.toThrow('BRIDGE_UNAVAILABLE');
  });
});
```

***

## 下一步

<CardGroup cols={2}>
  <Card title="API 参数" icon="settings" href="/composer/reference/api-parameters">
    完整 API 参数参考
  </Card>

  <Card title="支持的协议" icon="list" href="/composer/reference/supported-protocols">
    支持的协议完整列表
  </Card>

  <Card title="限制" icon="exclamation-triangle" href="/composer/reference/limitations">
    了解当前限制
  </Card>

  <Card title="状态跟踪" icon="clock" href="/introduction/user-flows-and-examples/status-tracking">
    跟踪交易状态
  </Card>
</CardGroup>
