处理 Capacitor SDK 中的错误

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

Tip

在调试前开启详细日志。 大多数 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 fetchFlow(placementId: string) {
  try {
    const flow = await adapty.getFlow({ placementId });
    return flow;
  } 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需要通过 activate 方法正确配置 Adapty SDK。具体操作请参阅安装与配置 Adapty SDK
productNotFound22所请求购买的产品在商店中不可用。
currentSubscriptionToUpdateNotFoundInHistory24未找到需要续订的原始订阅。
billingServiceTimeout97请求在 Google Play 响应前已超时。例如,Play Billing Library 调用所请求的操作执行延迟可能导致此问题。
featureNotSupported98当前设备的 Play Store 不支持所请求的功能。
billingServiceDisconnected99客户端应用通过 BillingClient 与 Google Play Store 服务的连接已断开,这是一个致命错误。
billingServiceUnavailable102Google Play 计费服务当前不可用(暂时性错误)。大多数情况下,这意味着客户端设备与 Google Play 计费服务之间存在网络连接问题。
billingUnavailable103

购买过程中发生用户计费错误。可能出现的情况包括:

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

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

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

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

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

developerError105致命错误,表示 API 使用方式不正确。
billingError106致命错误,表示 Google Play 内部出现问题。
itemAlreadyOwned107该消耗型商品已被购买。
itemNotOwned108对该商品执行的操作失败。
billingNetworkError112设备与 Play 系统之间的网络连接出现问题。

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

自定义网络错误码

错误错误码描述
notActivated2002需要通过 activate 方法正确配置 Adapty SDK。具体操作请参阅安装与配置 Adapty SDK
badRequest2003错误请求。
serverError2004服务器错误。
networkFailed2005网络请求失败。
decodingFailed2006响应解码失败。
encodingFailed2009请求编码失败。
analyticsDisabled3000由于你已选择退出,无法处理分析事件。详情请参阅分析集成
wrongParam3001部分参数不正确:不允许为空时为空,或类型错误等。
activateOnceError3005.activate 方法只能调用一次。
profileWasChanged3006操作期间用户画像已发生变更。
unsupportedData3007SDK 不支持该数据格式。
persistingDataError3100数据保存时出错。
fetchTimeoutError3101付费墙未能在规定时限内获取。为避免此情况,请设置本地备用方案
operationInterrupted9000此操作被系统中断。