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

# 错误

> SDK 的类型化错误，以及参数校验抛出的普通错误。

export const VersionBanner = ({network = 'mainnet', products = [], lang = 'en'}) => {
  const SDK_VERSION = '1.0.2';
  const ADDRESSES = {
    mainnet: {
      cpmm: {
        Router: 'ze15rnAwTyVCPnDhN7J8An3SvNeWBsZHAVMeBx1ehXeP',
        TokenPairFactory: '24CXRLvj1QiDH6riwr1EPERG7BcduHKZtktygbq97MfYb'
      },
      clmm: {
        PoolFactory: '24gqd4DMQXVzjm5QDAGxUtYupx3WM2PSu3vZUseuBCV9h',
        PositionManager: 'vFyKSqnJHS9MicrojBcLgztyRFqhS4hB349Ci3LJCELw'
      },
      staking: {
        XAlphToken: '225WevmFp5ZgzPsyVJTvyp2v2uyKrvp329HfrVmzffnWj',
        RewardFeeCollector: '22CE7vG6u64zjjsLZLxeJqQuPDydjPvbP9iG1d861j2G7'
      }
    },
    testnet: {
      cpmm: {
        Router: 'xaueT8kPMvpnaFJEfHv6CJLgqsSPpoNmHjF1QgTxoF9R',
        TokenPairFactory: '29hdd9b9Gp7oXuamwHKfUqBaRXP487HoeTcutS3RhZJEj'
      },
      clmm: {
        PoolFactory: 'z2QFT7qBQrfm8UwAYG3VHWoHs7B56ZDFNdSCcDu5j53m',
        PositionManager: '21p6egW8d6FEyVVuH17WqvHCARsCsD61GcBmeCr75XdGT'
      },
      staking: {
        XAlphToken: '23psDicimC5VdpM56wrgqgCzQzcyXWGCkQGSYWbtZAPRq',
        RewardFeeCollector: '29qQ1LPJ5uqawRviXLVDMeo19JUygRrNNTQy5RUBh817D'
      }
    }
  };
  const EXPLORERS = {
    mainnet: 'https://explorer.alephium.org/addresses/',
    testnet: 'https://testnet.alephium.org/addresses/'
  };
  const LABELS = {
    en: {
      sdk: 'SDK',
      network: 'Network',
      contracts: 'Contracts',
      all: 'All addresses',
      allNetworks: 'mainnet · testnet · devnet',
      devnet: 'Local deployment (addresses vary per devnet)'
    },
    zh: {
      sdk: 'SDK 版本',
      network: '网络',
      contracts: '合约',
      all: '全部地址',
      allNetworks: 'mainnet · testnet · devnet',
      devnet: '本地部署（每个 devnet 的地址不同）'
    },
    fr: {
      sdk: 'SDK',
      network: 'Réseau',
      contracts: 'Contrats',
      all: 'Toutes les adresses',
      allNetworks: 'mainnet · testnet · devnet',
      devnet: 'Déploiement local (adresses propres à chaque devnet)'
    }
  };
  const t = LABELS[lang] ?? LABELS.en;
  const contractsPage = lang === 'en' ? '/reference/contracts' : `/${lang}/reference/contracts`;
  const short = a => `${a.slice(0, 6)}…${a.slice(-4)}`;
  const entries = [];
  const addrs = ADDRESSES[network];
  if (addrs) {
    for (const p of products) {
      for (const [name, address] of Object.entries(addrs[p] ?? ({}))) entries.push({
        name,
        address
      });
    }
  }
  let contractsCell;
  if (network === 'devnet' && products.length > 0) {
    contractsCell = <span>{t.devnet}</span>;
  } else if (entries.length > 0) {
    contractsCell = entries.map(({name, address}, i) => <span key={name}>
        {i > 0 && <span className="mx-1 opacity-50">·</span>}
        {name}{' '}
        <a href={EXPLORERS[network] + address} target="_blank" rel="noreferrer" title={address}>
          <code>{short(address)}</code>
        </a>
      </span>);
  }
  const row = (label, value) => <div className="flex flex-wrap gap-x-2">
      <span className="font-semibold min-w-[5.5rem]">{label}</span>
      <span className="flex-1 min-w-0 break-words">{value}</span>
    </div>;
  return <div className="not-prose mb-6 rounded-xl border border-zinc-950/10 dark:border-white/10 bg-zinc-50 dark:bg-white/5 px-4 py-3 text-sm leading-6 text-zinc-700 dark:text-zinc-300">
      {row(t.sdk, <code>@alephium/powfi-sdk@{SDK_VERSION}</code>)}
      {row(t.network, network === 'all' ? t.allNetworks : network)}
      {contractsCell && row(t.contracts, <span>
            {contractsCell}
            <span className="mx-1 opacity-50">·</span>
            <a href={contractsPage}>{t.all} →</a>
          </span>)}
    </div>;
};

<VersionBanner network="mainnet" products={['cpmm', 'clmm', 'staking']} lang="zh" />

所有类型化错误都继承自 `PowfiSDKError`，后者继承自 `Error`。从包的根路径导入，并用 `instanceof` 判断：

```ts theme={null}
import {
  PowfiSDKError,
  PoolNotFoundError,
  PriceImpactTooHighError,
  InsufficientBalanceError,
  InsufficientLiquidityError
} from '@alephium/powfi-sdk'

try {
  await powfi.cpmm.swap(req, balances)
} catch (e) {
  if (e instanceof PriceImpactTooHighError) showWarning(e.message)
  else if (e instanceof InsufficientBalanceError) showTopUp(e.message)
  else if (e instanceof PoolNotFoundError) showCreatePool()
  else throw e
}
```

## 类型化错误

| 错误 | 抛出位置 | 消息 |
| - | - | - |
| `PoolNotFoundError` | `cpmm.getPoolState`、`clmm.getPoolState`、`clmm.getPoolTokenBalances`、`clmm.findBestRoute` | `Pool does not exist for <poolId>` |
| `PriceImpactTooHighError` | `cpmm.swap`，当 `priceImpact >= 5` 时 | `Price impact too high: 6.12% > 5%` |
| `InsufficientBalanceError` | `cpmm.swap`、`cpmm.addLiquidity`，当你传入 `balances` 映射时 | `Not enough <SYMBOL> balance. Required: …, Available: …` |
| `InsufficientLiquidityError` | `CpmmModule.getAmountIn`（输出 ≥ 储备量）、`getInitLiquidityDetails`（初始流动性 ≤ `MINIMUM_LIQUIDITY`） | `Insufficient liquidity` / 自定义 |
| `TokenListFetchError` | `token.fetchTokens`（会被包装，见下文） | `Failed to fetch token list from <url> (status 404)` |

`TokenListFetchError` 暴露 `status?: number`，原始错误在 `cause` 中。

<Note>
  部分模块方法会捕获错误，再以组合消息的普通 `Error` 重新抛出（通过 `logAndThrowError`），例如 `Failed to fetch pool state on <id>, <原始消息>`。`TokenModule.getTokens()` 和 `fetchTokens()` 就是这样：消息中包含 `TokenListFetchError` 的文本，但抛出的对象是 `Error`。如需区分，请匹配消息内容。
</Note>

## 参数校验错误（普通 `Error`）

| 消息 | 原因 |
| - | - |
| `Signer not set` | 在未传入 `signer` 的实例上调用了写入方法。 |
| `Network <id> not found` | 未知的 `networkId`。 |
| `Either amountIn or amountOut must be specified` | CPMM 报价既没有给出输入数量，也没有给出输出数量。 |
| `Slippage must satisfy 0 <= slippage < 10000, received …` | CPMM 的 `slippageBps` 无效。 |
| `slippageBps must be in [0, 10000)` | CLMM 的滑点无效。 |
| `Unknown tokenInId … for pool …` | 代币不属于你传入的池状态。 |
| `Unknown token, id not found in token list: …` | 代币不在代币列表中（查询池状态要求池中每个代币都在列表中）。 |
| `fee and feeRecipient must be provided together`（及其他手续费消息） | [集成方手续费](/zh/guides/integrator-fees)无效。 |
| `<Stake/Unstake/Claim> amount must be greater than zero` | 质押数量不为正数。 |
| `TickOutOfBounds: <tick>` / `SqrtPriceX96OutOfBounds` | tick 超出 `[MIN_TICK, MAX_TICK]`，或价格超出可表示范围。 |

## 链上错误

如果交易通过了 SDK 校验，但在合约中失败（超出滑点、超过截止时间、违反价格限制），节点会在签名阶段拒绝它，`@alephium/web3` 会抛出带有 VM 错误码的错误，例如 CLMM 兑换在全部成交之前就触及价格限制时，会报 `Error Code: 501`（如果价格限制位于当前价格的错误一侧，则报 `106`）。最常见的原因：

* **滑点或截止时间**：在报价和提交之间池发生了变化。请重新报价并重试。
* **ALPH 不足以支付粉尘或押金**：见 [ALPH 押金与粉尘](/zh/concepts/amounts-and-slippage)。
* **CLMM `swapTo` 方向或价格限制错误**：目标价格已经在当前价格的另一侧。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.