在 Capacitor SDK 中处理错误
SDK 返回的每个错误都是 AdaptyError 实例。以下是一个示例:
import { adapty, AdaptyError, ErrorCodeName } from '@adapty/capacitor';
try {
const result = await adapty.makePurchase({ product });
// Handle purchase result
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) {
console.error('Adapty error:', error.adaptyCode, error.localizedDescription);
// Handle specific error codes
switch (error.adaptyCode) {
case ErrorCodeName.cantMakePayments:
console.log('In-app purchases are not allowed on this device');
break;
case ErrorCodeName.notActivated:
console.log('Adapty SDK is not activated');
break;
case ErrorCodeName.productPurchaseFailed:
console.log('Purchase failed:', error.detail);
break;
default:
console.log('Other error occurred:', error.detail);
}
} else {
console.error('Non-Adapty error:', error);
}
}
错误属性
AdaptyError 类提供以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
adaptyCode | number | 数字错误代码(例如,1003 对应 cantMakePayments) |
localizedDescription | string | 用户友好的错误消息 |
detail | string | undefined | 附加错误详情(可选) |
message | string | 包含代码和描述的完整错误消息 |
错误代码
SDK 导出用于处理错误代码的常量和工具:
ErrorCodeName 常量
将字符串标识符映射到数字代码:
import { ErrorCodeName } from '@adapty/capacitor';
ErrorCodeName.cantMakePayments // 1003
ErrorCodeName.notActivated // 2002
ErrorCodeName.networkFailed // 2005
ErrorCode 常量
将数字代码映射到字符串标识符:
import { ErrorCode } from '@adapty/capacitor';
ErrorCode[1003] // 'cantMakePayments'
ErrorCode[2002] // 'notActivated'
ErrorCode[2005] // 'networkFailed'
辅助函数
import { getErrorCode, getErrorPrompt } from '@adapty/capacitor';
// 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 错误:
import { AdaptyError, ErrorCodeName } from '@adapty/capacitor';
// Set up global error handler
AdaptyError.onError = (error: AdaptyError) => {
console.error('Global Adapty error:', {
code: error.adaptyCode,
message: error.localizedDescription,
detail: error.detail
});
// Handle specific error types globally
if (error.adaptyCode === ErrorCodeName.notActivated) {
// SDK not activated - maybe retry activation
console.log('SDK not activated, attempting to reactivate...');
}
};
常见错误处理模式
处理购买错误
import { adapty, AdaptyError, ErrorCodeName } from '@adapty/capacitor';
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);
}
}
}
}
处理网络错误
import { adapty, AdaptyError, ErrorCodeName } from '@adapty/capacitor';
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 错误代码
| 错误 | 代码 | 描述 |
|---|---|---|
| unknown | 0 | 此错误表示发生了未知或意外的错误。 |
| clientInvalid | 1 | 此错误代码表示客户端不被允许执行所尝试的操作。 |
| paymentCancelled | 2 | 此错误代码表示用户取消了付款请求。 无需采取任何操作,但从业务逻辑角度,您可以向用户提供折扣或稍后提醒他们。 |
| paymentInvalid | 3 | 此错误表示商店无法识别某个付款参数。 |
| paymentNotAllowed | 4 | 此错误代码表示用户不被允许授权付款。可能的原因: - 用户所在国家/地区不支持付款。 - 用户未成年。 |
| storeProductNotAvailable | 5 | 此错误代码表示所请求的产品在 App Store 中不存在。请确保该产品在所使用的国家/地区可用。 |
| cloudServicePermissionDenied | 6 | 此错误代码表示用户尚未允许访问云服务信息。 |
| cloudServiceNetworkConnectionFailed | 7 | 此错误代码表示设备无法连接到网络。 |
| cloudServiceRevoked | 8 | 此错误代码表示用户已撤销使用此云服务的权限。 |
| privacyAcknowledgementRequired | 9 | 此错误代码表示用户尚未确认商店隐私政策。 |
| unauthorizedRequestData | 10 | 此错误代码表示请求构建不正确。 |
| invalidOfferIdentifier | 11 | 优惠标识符无效。可能的原因: - 您尚未在 App Store 中设置具有该标识符的优惠。 - 您已撤销该优惠。 - 您误输了优惠 ID。 |
| invalidSignature | 12 | 此错误代码表示付款折扣中的签名无效。请确保您已填写 In-app purchase Key ID 字段并上传了 In-App Purchase Private Key 文件。详情请参阅配置 App Store 集成主题。 |
| missingOfferParams | 13 | 此错误表示 Adapty 集成或优惠存在问题。 有关如何设置的详情,请参阅配置 App Store 集成和优惠。 |
| invalidOfferPrice | 14 | 此错误代码表示您在商店中指定的价格已不再有效。优惠必须始终代表折扣价格。 |
自定义 Android 错误代码
| 错误 | 代码 | 描述 |
|---|---|---|
| adaptyNotInitialized | 20 | 您需要通过 Adapty.activate 方法正确配置 Adapty SDK。了解如何为 React Native 配置。 |
| productNotFound | 22 | 此错误表示所请求购买的产品在商店中不可用。 |
| invalidJson | 23 | 付费墙 JSON 无效。请在 Adapty 控制台中修复它。有关如何修复的详情,请参阅使用远程配置自定义付费墙主题。 |
| currentSubscriptionToUpdateNotFoundInHistory | 24 | 未找到需要续订的原始订阅。 |
| pendingPurchase | 25 | 此错误表示购买状态为待处理而非已购买。详情请参阅 Android 开发者文档中的处理待处理交易页面。 |
| billingServiceTimeout | 97 | 此错误表示请求在 Google Play 响应之前已达到最大超时时间。例如,这可能是由 Play Billing Library 调用所请求操作的执行延迟引起的。 |
| featureNotSupported | 98 | 当前设备上的 Play Store 不支持所请求的功能。 |
| billingServiceDisconnected | 99 | 此严重错误表示客户端应用通过 BillingClient 与 Google Play Store 服务的连接已断开。 |
| billingServiceUnavailable | 102 | 此暂时性错误表示 Google Play Billing 服务当前不可用。在大多数情况下,这意味着客户端设备与 Google Play Billing 服务之间的某处存在网络连接问题。 |
| billingUnavailable | 103 | 此错误表示在购买过程中发生了用户计费错误。可能发生此情况的示例包括: 1. 用户设备上的 Play Store 应用已过期。 2. 用户位于不受支持的国家/地区。 3. 用户是企业用户,且其企业管理员已禁止用户进行购买。 4. Google Play 无法向用户的付款方式收费。例如,用户的信用卡可能已过期。 5. 用户未登录 Play Store 应用。 |
| developerError | 105 | 这是一个严重错误,表示您未正确使用某个 API。 |
| billingError | 106 | 这是一个严重错误,表示 Google Play 本身存在内部问题。 |
| itemAlreadyOwned | 107 | 消耗型商品已被购买。 |
| itemNotOwned | 108 | 此错误表示对该商品所请求的操作失败。 |
自定义 StoreKit 错误代码
| 错误 | 代码 | 描述 |
|---|---|---|
| noProductIDsFound | 1000 | 此错误表示付费墙中没有任何产品在商店中可用。 如果您遇到此错误,请按照以下步骤解决: 1. 检查所有产品是否已添加到 Adapty 控制台。 2. 确保您应用的 Bundle ID 与 Apple Connect 中的 Bundle ID 一致。 3. 验证应用商店中的产品标识符与您添加到控制台中的标识符一致。请注意,标识符不应包含 Bundle ID,除非商店中已包含它。 4. 确认您的 Apple 税务设置中应用付费状态为有效。确保您的税务信息是最新的,且证书有效。 5. 检查是否已关联银行账户,以便应用有资格进行货币化。 6. 检查产品是否在所有地区可用。同时,确保您的产品处于 “Ready to Submit” 状态。 |
| productRequestFailed | 1002 | 当前无法获取可用产品。可能的原因: - 尚未创建缓存,同时也没有网络连接。 |
| cantMakePayments | 1003 | 此设备不允许进行应用内购买。 |
| noPurchasesToRestore | 1004 | 此错误表示 Google Play 未找到可恢复的购买记录。 |
| cantReadReceipt | 1005 | 设备上没有有效的收据。这在沙盒测试期间可能是一个问题。 无需采取任何操作,但从业务逻辑角度,您可以向用户提供折扣或稍后提醒他们。 |
| productPurchaseFailed | 1006 | 产品购买失败。 |
| refreshReceiptFailed | 1010 | 此错误表示未收到收据。仅适用于 StoreKit 1。 |
| receiveRestoredTransactionsFailed | 1011 | 购买恢复失败。 |
自定义网络错误代码
| 错误 | 代码 | 描述 |
|---|---|---|
| notActivated | 2002 | 您需要通过 Adapty.activate 方法正确配置 Adapty SDK。了解如何为 React Native 配置。 |
| badRequest | 2003 | 错误请求。 |
| serverError | 2004 | 服务器错误。 |
| networkFailed | 2005 | 网络请求失败。 |
| decodingFailed | 2006 | 此错误表示响应解码失败。 |
| encodingFailed | 2009 | 此错误表示请求编码失败。 |
| analyticsDisabled | 3000 | 由于您已选择退出,我们无法处理分析事件。详情请参阅分析集成主题。 |
| wrongParam | 3001 | 此错误表示您的某些参数不正确:不能为空时为空,或类型错误等。 |
| activateOnceError | 3005 | 不能多次调用 .activate 方法。 |
| profileWasChanged | 3006 | 操作期间用户画像已更改。 |
| fetchTimeoutError | 3101 | 此错误表示付费墙未能在设定的时间限制内获取。为避免此情况,请设置本地备用方案。 |
| operationInterrupted | 9000 | 此操作被系统中断。 |