跳转到主要内容

错误处理

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

API 错误

当 API 调用失败时,响应中会包含错误消息:
{
  "error": "No route found"
}
错误原因解决方案
No route found两个代币之间不存在流动性路径验证代币地址;检查池是否存在
Invalid token address地址格式错误使用校验和格式或小写十六进制地址
Amount must be positive金额为零或负数提供有效的正数金额字符串
Invalid tradeTypetradeType 不是 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 与所需输入金额一致

钱包错误

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)

检查授权状态

// 检查 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));

最佳实践

预检查

在执行交换前,请验证:
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 重试