Capacitor SDKのエラー処理
SDKから返されるすべてのエラーはAdaptyErrorインスタンスです。以下に例を示します:
デバッグ前に詳細ログを有効にしてください。 ほとんどのAdaptyErrorは、StoreKit・Play Billing・ネットワーク・バックエンドのエラーをラップしています。詳細ログを有効にする(adapty.setLogLevel({ logLevel: 'verbose' }))と — ログを参照 — ラップされたエラーがコンソールに出力され、実際の原因を特定しやすくなります。AdaptyErrorのdetailプロパティはログレベルに関わらず設定されますが、詳細ログを有効にすることでコンソールにも表示されます。
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 | 数値エラーコード(例:cantMakePaymentsの場合は1003) |
localizedDescription | string | ユーザー向けのエラーメッセージ |
detail | string | undefined | 追加のエラー詳細(任意) |
message | string | コードと説明を含む完全なエラーメッセージ |
エラーコード
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エラーをキャッチするグローバルエラーハンドラーを設定できます:
// 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...');
}
};
よくあるエラー処理パターン
購入エラーの処理
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 コード
| エラー | コード | 説明 |
|---|---|---|
| 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 のものと一致しているか確認する。 3. アプリストアのプロダクト識別子がダッシュボードに追加したものと一致しているか確認する。識別子にはストアにすでに含まれている場合を除き、Bundle ID を含めないこと。 4. Apple の税務設定でアプリの有料ステータスがアクティブになっているか確認する。税務情報が最新であり、証明書が有効であることを確認する。 5. アプリに銀行口座が紐付けられており、収益化の対象になっているか確認する。 6. プロダクトがすべての地域で利用可能になっているか確認する。また、プロダクトのステータスが “Ready to Submit” になっていることを確認する。 |
| productRequestFailed | 1002 | 現時点で利用可能なプロダクトを取得できません。考えられる原因: - キャッシュがまだ作成されておらず、同時にインターネット接続もない。 |
| cantMakePayments | 1003 | このデバイスではアプリ内課金が許可されていません。 |
| noPurchasesToRestore | 1004 | Google Play が復元対象の購入を見つけられなかったことを示します。 |
| cantReadReceipt | 1005 | デバイス上に有効なレシートがありません。サンドボックステスト中に発生することがあります。 特に対応は不要ですが、ビジネスロジックの観点から、ユーザーに割引を提示したり、後でリマインドしたりすることができます。 |
| productPurchaseFailed | 1006 | プロダクトの購入に失敗しました。このエラーは内部の StoreKit エラーをラップしています。実際の原因を確認するには、ラップされたエラーを読み取るか(または詳細ログを有効にしてコンソールで確認)してください。ラップされたエラーは通常、上記の StoreKit コード 0〜14 のいずれかで、最も多いのは paymentCancelled、paymentInvalid、paymentNotAllowed、invalidOfferPrice です。原因が特定できない場合は、新しいサンドボックスプロファイルでお試しください。それでも解決しない場合は Apple サポートにお問い合わせください。 |
| 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 | この操作はシステムによって中断されました。 |