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

# 错误处理

> 常见错误、错误码及处理策略

# 错误处理

本指南涵盖了集成 Kroko DEX 时会遇到的常见错误及其处理方法。

## API 错误

当 API 调用失败时，响应中会包含错误消息：

```json theme={null}
{
  "error": "No route found"
}
```

| 错误                        | 原因                 | 解决方案                                   |
| ------------------------- | ------------------ | -------------------------------------- |
| `No route found`          | 两个代币之间不存在流动性路径     | 验证代币地址；检查池是否存在                         |
| `Invalid token address`   | 地址格式错误             | 使用校验和格式或小写十六进制地址                       |
| `Amount must be positive` | 金额为零或负数            | 提供有效的正数金额字符串                           |
| `Invalid tradeType`       | tradeType 不是 0 或 1 | 使用 `0`（Exact Input）或 `1`（Exact Output） |

## 交易错误

### 链上回滚

这些错误发生在交易已提交但在链上回滚时：

| 错误                      | 原因                        | 解决方案                         |
| ----------------------- | ------------------------- | ---------------------------- |
| `TRANSFER_FROM_FAILED`  | 代币授权不足或余额不足               | 检查 Permit2 授权（步骤 1 和 2）及代币余额 |
| `EXPIRED`               | 交易截止时间已过                  | 使用更长的截止时间或尽快重新提交             |
| `V3_INVALID_AMOUNT_OUT` | 产出低于 `minAmountOut`（滑点超限） | 增加滑点容差或减小交易规模                |
| `INSUFFICIENT_ETH`      | 发送的原生 KAS 作为 `value` 不足   | 确保 `value` 与所需输入金额一致         |

### 钱包错误

```typescript theme={null}
try {
  const tx = await signer.sendTransaction(swapData);
  await tx.wait();
} catch (error) {
  if (error.code === 'ACTION_REJECTED' || error.code === 4001) {
    // 用户在钱包中拒绝了交易
    console.log('交易已被用户取消');
    return;
  }

  if (error.code === 'ERR_NETWORK') {
    // 网络连接问题
    console.log('网络错误 — 请检查你的连接');
    return;
  }

  // 其他错误
  console.error('交易失败：', error.message);
}
```

## 授权错误

授权流程中的常见问题：

| 症状                       | 原因             | 修复方法                                      |
| ------------------------ | -------------- | ----------------------------------------- |
| 授权成功后交换仍失败               | 授权了错误的合约       | 确保步骤 1 授权的是 Permit2（而非 Universal Router）  |
| Permit2 授权成功但交换失败        | Permit2 子授权已过期 | 检查过期时间并在需要时重新授权                           |
| "Insufficient allowance" | 授权金额小于交换金额     | 授权 `MaxUint256`（步骤 1）或 `MaxUint160`（步骤 2） |

### 检查授权状态

```typescript theme={null}
// 检查 ERC-20 → Permit2 授权
const tokenAllowance = await token.allowance(userAddress, PERMIT2);
console.log('Token → Permit2:', tokenAllowance.toString());

// 检查 Permit2 → Universal Router 授权
const [amount, expiration] = await permit2.allowance(
  userAddress, tokenAddress, UNIVERSAL_ROUTER
);
console.log('Permit2 → Router:', amount.toString());
console.log('过期时间:', new Date(Number(expiration) * 1000));
```

## 最佳实践

### 预检查

在执行交换前，请验证：

```typescript theme={null}
async function preflightCheck(userAddress, tokenIn, amountIn) {
  // 1. 检查余额
  const balance = await token.balanceOf(userAddress);
  if (balance < amountIn) {
    throw new Error(`余额不足：拥有 ${balance}，需要 ${amountIn}`);
  }

  // 2. 检查 ERC-20 对 Permit2 的授权
  const allowance = await token.allowance(userAddress, PERMIT2);
  if (allowance < amountIn) {
    return { needsApproval: 'token' };
  }

  // 3. 检查 Permit2 子授权
  const [amount, expiration] = await permit2.allowance(
    userAddress, tokenIn, UNIVERSAL_ROUTER
  );
  if (amount < amountIn || expiration < Math.floor(Date.now() / 1000)) {
    return { needsApproval: 'permit2' };
  }

  return { needsApproval: null };
}
```

### 重试策略

* **API 错误**：可以立即重试（短暂的网络问题）
* **链上回滚**：不要盲目重试 — 先诊断原因
* **用户拒绝**：不要重试 — 等待用户再次发起
* **滑点错误**：重新获取报价（价格可能已变化），使用新的 calldata 重试
