处理 Capacitor SDK 中的错误

SDK 返回的每个错误都是一个 AdaptyError 实例。示例如下:

在调试前开启详细日志。 大多数 AdaptyError 都封装了底层的 StoreKit、Play Billing、网络或后端错误。开启详细日志(adapty.setLogLevel({ logLevel: 'verbose' }),参见日志记录)后,这些封装的错误会打印到控制台,通常能直接告诉你真正的原因。无论日志级别如何,AdaptyError 上的 detail 属性都会被填充——详细日志只是让它显示在控制台中。


try {
  const result = await adapty.makePurchase({ product });
  
  // 处理购买结果
  if (result.type === 'success') {
    console.log('购买成功:', result.profile);
  } else if (result.type === 'user_cancelled') {
    console.log('用户取消了购买');
  } else if (result.type === 'pending') {
    console.log('购买待处理中');
  }
} catch (error) {
  if (error instanceof AdaptyError) {
    console.error('Adapty 错误:', error.adaptyCode, error.localizedDescription);
    
    // 处理特定错误码
    switch (error.adaptyCode) {
      case ErrorCodeName.cantMakePayments:
        console.log('此设备不允许应用内购买');
        break;
      case ErrorCodeName.notActivated:
        console.log('Adapty SDK 未激活');
        break;
      case ErrorCodeName.productPurchaseFailed:
        console.log('购买失败:', error.detail);
        break;
      default:
        console.log('发生其他错误:', error.detail);
    }
  } else {
    console.error('非 Adapty 错误:', error);
  }
}

错误属性

AdaptyError 类提供以下属性:

属性类型描述
adaptyCodenumber数字错误代码(例如,1003 对应 cantMakePayments)
localizedDescriptionstring用户友好的错误消息
detailstring | undefined附加错误详情(可选)
messagestring包含代码和描述的完整错误消息

错误代码

SDK 导出用于处理错误代码的常量和工具:

ErrorCodeName 常量

将字符串标识符映射到数字代码:


ErrorCodeName.cantMakePayments // 1003
ErrorCodeName.notActivated // 2002
ErrorCodeName.networkFailed // 2005

ErrorCode 常量

将数字代码映射到字符串标识符:


ErrorCode[1003] // 'cantMakePayments'
ErrorCode[2002] // 'notActivated'
ErrorCode[2005] // 'networkFailed'

辅助函数


// Get numeric code from string name:
getErrorCode('cantMakePayments') // 1003

// Get string name from numeric code:
getErrorPrompt(1003) // 'cantMakePayments'

比较错误代码

重要提示: error.adaptyCode 是一个 数字,因此应直接与数字代码进行比较:

// Option 1: Use ErrorCodeName constant (recommended) ✅
if (error.adaptyCode === ErrorCodeName.cantMakePayments) {
  console.log('Cannot make payments');
}

// Option 2: Compare with numeric literal ✅
if (error.adaptyCode === 1003) {
  console.log('Cannot make payments');
}

// NOT like this ❌ - compares number to string and will never match
if (error.adaptyCode === ErrorCode[1003]) {
}

全局错误处理器

你可以设置一个全局错误处理器来捕获所有 Adapty 错误:


// 设置全局错误处理器
AdaptyError.onError = (error: AdaptyError) => {
  console.error('Global Adapty error:', {
    code: error.adaptyCode,
    message: error.localizedDescription,
    detail: error.detail
  });
  
  // 全局处理特定错误类型
  if (error.adaptyCode === ErrorCodeName.notActivated) {
    // SDK 未激活 - 可以尝试重新激活
    console.log('SDK not activated, attempting to reactivate...');
  }
};

常见错误处理模式

处理购买错误


async function handlePurchase(product: AdaptyPaywallProduct) {
  try {
    const result = await adapty.makePurchase({ product });
    
    if (result.type === 'success') {
      console.log('Purchase successful:', result.profile);
    } else if (result.type === 'user_cancelled') {
      console.log('User cancelled the purchase');
    } else if (result.type === 'pending') {
      console.log('Purchase is pending');
    }
  } catch (error) {
    if (error instanceof AdaptyError) {
      switch (error.adaptyCode) {
        case ErrorCodeName.cantMakePayments:
          console.log('In-app purchases not allowed');
          break;
        case ErrorCodeName.productPurchaseFailed:
          console.log('Purchase failed:', error.detail);
          break;
        default:
          console.error('Purchase error:', error.localizedDescription);
      }
    }
  }
}

处理网络错误


async function fetchPaywall(placementId: string) {
  try {
    const paywall = await adapty.getPaywall({ placementId });
    return paywall;
  } catch (error) {
    if (error instanceof AdaptyError) {
      switch (error.adaptyCode) {
        case ErrorCodeName.networkFailed:
          console.log('Network error, retrying...');
          // Implement retry logic
          break;
        case ErrorCodeName.serverError:
          console.log('Server error:', error.detail);
          break;
        case ErrorCodeName.notActivated:
          console.log('SDK not activated');
          break;
        default:
          console.error('Paywall fetch error:', error.localizedDescription);
      }
    }
    throw error;
  }
}

系统 StoreKit 错误码

错误错误码描述
unknown0发生了未知或意外的错误。
clientInvalid1客户端不被允许执行该操作。
paymentCancelled2

用户取消了支付请求。

无需采取额外操作,但从业务逻辑角度,你可以向用户提供折扣或稍后再次提醒。

paymentInvalid3支付参数中有一项未被商店识别。
paymentNotAllowed4

用户不被允许进行支付授权。可能的原因:

- 该用户所在国家/地区不支持支付。

- 用户未成年。

storeProductNotAvailable5请求的产品在 App Store 中不存在。请确认该产品在对应国家/地区可用。
cloudServicePermissionDenied6用户未授权访问云服务信息。
cloudServiceNetworkConnectionFailed7设备无法连接到网络。
cloudServiceRevoked8用户已撤销对该云服务的使用权限。
privacyAcknowledgementRequired9用户尚未确认商店隐私政策。
unauthorizedRequestData10请求构建有误。
invalidOfferIdentifier11

优惠标识符无效。可能的原因:

- 你未在 App Store 中设置该标识符对应的优惠。

- 该优惠已被撤销。

- 优惠 ID 填写有误。

invalidSignature12支付折扣中的签名无效。请确认你已填写 In-app purchase Key ID 字段并上传了 In-App Purchase Private Key 文件。详情请参阅 配置 App Store 集成
missingOfferParams13

Adapty 集成或优惠配置存在问题。

详情请参阅 配置 App Store 集成优惠

invalidOfferPrice14你在商店中指定的价格已失效。优惠价格必须低于原价。

自定义 Android 错误码

错误错误码描述
adaptyNotInitialized20你需要通过 Adapty.activate 方法正确配置 Adapty SDK。了解如何 在 React Native 中配置
productNotFound22请求购买的产品在商店中不可用。
invalidJson23付费墙 JSON 格式无效。请在 Adapty 看板中修复它。详情请参阅 使用远程配置自定义付费墙
currentSubscriptionToUpdateNotFoundInHistory24未找到需要续订的原始订阅记录。
pendingPurchase25购买状态为待处理,而非已完成。详情请参阅 Android 开发者文档中的 处理待处理交易 页面。
billingServiceTimeout97请求在 Google Play 响应前已达到最大超时时间。例如,Play Billing Library 调用请求的操作执行出现延迟时可能触发此错误。
featureNotSupported98当前设备上的 Play Store 不支持该功能。
billingServiceDisconnected99这是一个致命错误,表示客户端应用与 Google Play Store 服务之间通过 BillingClient 建立的连接已断开。
billingServiceUnavailable102这是一个暂时性错误,表示 Google Play 结算服务当前不可用。大多数情况下,这意味着客户端设备与 Google Play 结算服务之间的网络连接存在问题。
billingUnavailable103

购买过程中发生了用户结算错误。常见原因包括:

1. 用户设备上的 Play Store 应用版本过旧。

2. 用户所在国家/地区不受支持。

3. 用户为企业用户,且其企业管理员已禁止用户进行购买。

4. Google Play 无法向用户的支付方式扣款,例如用户的信用卡已过期。

5. 用户未登录 Play Store 应用。

developerError105这是一个致命错误,表示你正在不正确地使用某个 API。
billingError106这是一个致命错误,表示 Google Play 内部出现了问题。
itemAlreadyOwned107该消耗型商品已被购买。
itemNotOwned108对该商品执行的请求操作失败。

自定义 StoreKit 错误码

错误错误码描述
noProductIDsFound1000

付费墙中的所有产品均无法在商店中找到。

如果遇到此错误,请按以下步骤排查:

1. 检查所有产品是否已添加到 Adapty 看板。

2. 确认应用的 Bundle ID 与 Apple Connect 中的一致。

3. 核实应用商店中的产品标识符与看板中添加的标识符一致。请注意,标识符中不应包含 Bundle ID,除非商店本身已包含它。

4. 确认你的 Apple 税务设置中应用的付费状态为有效,税务信息为最新,且证书有效。

5. 检查应用是否已绑定银行账户,以便具备变现资格。

6. 检查产品是否在所有地区可用,并确保产品状态为 “Ready to Submit”

productRequestFailed1002

当前无法获取可用产品。可能的原因:

- 尚未创建缓存,同时也没有网络连接。

cantMakePayments1003此设备不允许进行应用内购买。
noPurchasesToRestore1004Google Play 未找到可恢复的购买记录。
cantReadReceipt1005

设备上没有有效的收据。这在沙盒测试期间可能出现。

无需采取额外操作,但从业务逻辑角度,你可以向用户提供折扣或稍后再次提醒。

productPurchaseFailed1006产品购买失败。此错误封装了底层 StoreKit 错误——请读取被封装的错误(或开启详细日志以在控制台查看)以获取实际原因。被封装的错误通常是上表中错误码 0–14 之一,最常见的是 paymentCancelledpaymentInvalidpaymentNotAllowedinvalidOfferPrice。如果无法确定具体原因,请尝试新建一个沙盒用户画像;若问题依然存在,请联系 Apple 支持。
refreshReceiptFailed1010未收到收据。仅适用于 StoreKit 1。
receiveRestoredTransactionsFailed1011购买恢复失败。

自定义网络错误码

错误错误码描述
notActivated2002你需要通过 Adapty.activate 方法正确配置 Adapty SDK。了解如何 在 React Native 中配置
badRequest2003请求无效。
serverError2004服务器错误。
networkFailed2005网络请求失败。
decodingFailed2006响应解码失败。
encodingFailed2009请求编码失败。
analyticsDisabled3000由于你已选择退出,我们无法处理分析事件。详情请参阅 分析集成
wrongParam3001部分参数不正确:不能为空时传入了空值,或类型有误等。
activateOnceError3005.activate 方法只能调用一次。
profileWasChanged3006操作执行期间用户画像发生了变更。
fetchTimeoutError3101付费墙未能在规定时间内获取完成。为避免此问题,请 设置本地备用方案
operationInterrupted9000该操作被系统中断。