Обработка ошибок в Capacitor SDK

Каждая ошибка, возвращаемая SDK, является экземпляром AdaptyError. Пример:

Tip

Включите подробные логи перед отладкой. Большинство AdaptyError оборачивают исходную ошибку StoreKit, Play Billing, сети или бэкенда. При включённых подробных логах (adapty.setLogLevel({ logLevel: 'verbose' }) — см. Логирование) обёрнутая ошибка выводится в консоль, что обычно сразу указывает на реальную причину. Свойство detail у AdaptyError заполняется вне зависимости от уровня логирования — подробные логи просто выводят его в консоль.


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('SDK Adapty не активирован');
        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:


// 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 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 не настроен оффер с таким идентификатором.

- Оффер был отозван.

- Идентификатор оффера указан с опечаткой.

invalidSignature12Подпись в платёжной скидке недействительна. Убедитесь, что вы заполнили поле In-app purchase Key ID и загрузили файл In-App Purchase Private Key. Подробнее — в разделе Configure App Store integration.
missingOfferParams13

Проблемы с интеграцией Adapty или с офферами.

Подробнее о настройке — в разделах Configure App Store integration и Offers.

invalidOfferPrice14Указанная в сторе цена больше не действительна. Офферы всегда должны представлять сниженную цену.

Пользовательские коды Android

ОшибкаКодОписание
adaptyNotInitialized20Необходимо правильно настроить Adapty SDK с помощью метода activate. Подробнее — в разделе Install & configure Adapty SDK.
productNotFound22Запрошенный для покупки продукт недоступен в сторе.
currentSubscriptionToUpdateNotFoundInHistory24Исходная подписка, которую необходимо продлить, не найдена.
billingServiceTimeout97Запрос достиг максимального таймаута до получения ответа от Google Play. Это может быть вызвано, например, задержкой при выполнении действия, запрошенного вызовом Play Billing Library.
featureNotSupported98Запрошенная функция не поддерживается Play Store на данном устройстве.
billingServiceDisconnected99Критическая ошибка: соединение клиентского приложения со службой Google Play Store через BillingClient было разорвано.
billingServiceUnavailable102Временная ошибка: служба Google Play Billing в данный момент недоступна. В большинстве случаев это означает проблему с сетевым подключением между устройством и серверами Google Play Billing.
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 в таблице выше — чаще всего paymentCancelled, paymentInvalid, paymentNotAllowed или invalidOfferPrice. Если не удаётся определить конкретную причину, попробуйте создать новый профиль песочницы; если ошибка воспроизводится, обратитесь в службу поддержки Apple.
refreshReceiptFailed1010Чек не был получен. Применимо только к StoreKit 1.
receiveRestoredTransactionsFailed1011Восстановление покупок не удалось.

Пользовательские сетевые коды

ОшибкаКодОписание
notActivated2002Необходимо правильно настроить Adapty SDK с помощью метода activate. Подробнее — в разделе Install & configure Adapty SDK.
badRequest2003Некорректный запрос.
serverError2004Ошибка сервера.
networkFailed2005Сетевой запрос завершился с ошибкой.
decodingFailed2006Ошибка декодирования ответа.
encodingFailed2009Ошибка кодирования запроса.
analyticsDisabled3000Невозможно обработать аналитические события, так как вы отказались от их сбора. Подробнее — в разделе Analytics integration.
wrongParam3001Один или несколько параметров указаны некорректно: пустое значение там, где оно не допускается, неверный тип и т. д.
activateOnceError3005Метод .activate нельзя вызывать более одного раза.
profileWasChanged3006Профиль пользователя был изменён в процессе операции.
unsupportedData3007Формат данных не поддерживается SDK.
persistingDataError3100Ошибка при сохранении данных.
fetchTimeoutError3101Пейвол не удалось загрузить в отведённое время. Чтобы избежать этой ситуации, настройте локальные резервные пейволы.
operationInterrupted9000Операция была прервана системой.