入门

错误处理

SDK 的错误层次结构和最佳实践,帮助你写出健壮的代码

概述

SDK 默认从 errors.ts 导出以下错误类。了解这些错误类型可以帮助你更精确地捕获和处理异常。

错误层次结构

所有 SDK 错误都继承自 BaseError,按功能模块分为多个子类:

基础错误
  • BaseError - 所有 SDK 错误的基类
  • ArgumentError - 参数错误
  • IllegalArgumentError - 非法参数
  • ArgumentCountMismatchError - 参数数量不匹配
  • InsufficientBalanceError - 余额不足
  • MissingParamError - 缺少参数
  • TypeError - 类型错误
  • LogicError - 逻辑错误
账户错误 (AccountError)
  • UnavailableAccountError - 账户不可用
AENS 错误 (AensError)
  • AensPointerContextError - 指针上下文错误
  • InsufficientNameFeeError - 域名费不足
  • InvalidAensNameError - 无效域名
合约错误 (ContractError)
  • BytecodeMismatchError - 字节码不匹配
  • DuplicateContractError - 合约重复
  • InactiveContractError - 合约未激活
  • InvalidMethodInvocationError - 方法调用无效
  • MissingContractAddressError - 缺少合约地址
  • NodeInvocationError - 节点调用错误
  • NoSuchContractFunctionError - 合约函数不存在
  • NotPayableFunctionError - 函数不可支付
交易错误 (TransactionError)
  • DecodeError - 解码错误
  • DryRunError - 干运行错误
  • InvalidSignatureError - 签名无效
  • InvalidTxError - 交易无效
  • TxNotInChainError - 交易不在链上
  • TxTimedOutError - 交易超时
钱包错误 (WalletError)
  • AlreadyConnectedError - 已连接
  • NoWalletConnectedError - 未连接钱包
  • RpcConnectionError - RPC 连接错误
RPC 错误 (RpcError)
  • RpcRejectedByUserError - 用户拒绝
  • RpcConnectionDenyError - 连接被拒
  • RpcPermissionDenyError - 权限被拒
其他错误
  • ChannelError - 状态通道错误
  • CompilerError - 编译器错误
  • CryptographyError - 密码学错误
  • NodeError - 节点错误
  • InternalError - 内部错误
  • RequestTimedOutError - 请求超时
基本用法

捕获并处理特定类型的错误:

import {
  AeSdk,
  Node,
  AccountMemory,
  ArgumentError,
  InvalidAensNameError,
} from '@aeternity/aepp-sdk';

// 初始化
const payerAccount = AccountMemory.generate();
const newUserAccount = AccountMemory.generate();
const node = new Node('https://testnet.aeternity.io');

const aeSdk = new AeSdk({
  nodes: [{ name: 'testnet', instance: node }],
  accounts: [payerAccount, newUserAccount],
});

// 捕获异常
try {
  const spendTxResult = await aeSdk.spend(
    -1,  // 无效金额
    newUserAccount.address,
    { onAccount: payerAccount }
  );
} catch (err) {
  if (err instanceof ArgumentError) {
    console.log(`金额无效: ${err.message}`);
  } else if (err instanceof InvalidAensNameError) {
    console.log(`地址无效: ${err.message}`);
  }
}
使用通用错误类

如果你不需要区分具体的错误类型,可以使用更通用的错误父类:

import { 
  AensError, 
  TransactionError, 
  BaseError 
} from '@aeternity/aepp-sdk';

try {
  const spendTxResult = await aeSdk.spend(1, 'ak_2tv', { onAccount: payerAccount });
} catch (err) {
  if (err instanceof AensError) {
    // 处理所有 AENS 相关错误
    console.error('AENS 操作失败:', err.message);
  } else if (err instanceof TransactionError) {
    // 处理所有交易相关错误
    console.error('交易失败:', err.message);
  } else if (err instanceof BaseError) {
    // 匹配所有 SDK 错误
    console.error('SDK 错误:', err.message);
  } else {
    // 其他非 SDK 错误
    throw err;
  }
}
提示:使用 BaseError 可以捕获所有 SDK 抛出的错误,而不会影响其他类型的异常。
最佳实践
优先捕获具体错误

先处理具体错误类型,再处理通用错误

记录错误详情

err.message 和堆栈输出到日志

用户友好提示

向用户展示可理解的错误信息

重新抛出未知错误

不要吞掉无法处理的异常