---
title: "Обработка ошибок в Capacitor SDK"
description: "Обработка ошибок в Capacitor SDK."
---

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

```typescript showLineNumbers

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);
  }
}
```

## Свойства ошибки \{#error-properties\}

Класс `AdaptyError` предоставляет следующие свойства:

| Свойство | Тип | Описание |
|----------|------|-------------|
| `adaptyCode` | `number` | Числовой код ошибки (например, `1003` для cantMakePayments) |
| `localizedDescription` | `string` | Понятное пользователю сообщение об ошибке |
| `detail` | `string \| undefined` | Дополнительная информация об ошибке (необязательно) |
| `message` | `string` | Полное сообщение об ошибке с кодом и описанием |

## Коды ошибок \{#error-codes\}

SDK экспортирует константы и утилиты для работы с кодами ошибок:

### Константа ErrorCodeName \{#errorcodename-constant\}

Сопоставляет строковые идентификаторы с числовыми кодами:

```typescript

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

### Константа ErrorCode \{#errorcode-constant\}

Сопоставляет числовые коды со строковыми идентификаторами:

```typescript

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

### Вспомогательные функции \{#helper-functions\}

```typescript

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

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

### Сравнение кодов ошибок \{#comparing-error-codes\}

**Важно:** `error.adaptyCode` — это **число**, поэтому сравнивайте его напрямую с числовыми кодами:

```typescript
// 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]) {
}
```

## Глобальный обработчик ошибок \{#global-error-handler\}

Вы можете настроить глобальный обработчик для перехвата всех ошибок Adapty:

```typescript showLineNumbers

// 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...');
  }
};
```

## Типовые паттерны обработки ошибок \{#common-error-handling-patterns\}

### Обработка ошибок покупки \{#handle-purchase-errors\}

```typescript showLineNumbers

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);
      }
    }
  }
}
```

### Обработка сетевых ошибок \{#handle-network-errors\}

```typescript showLineNumbers

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 \{#system-storekit-codes\}

| Ошибка | Код | Описание |
|-----|----|-----------|
| unknown | 0 | Неизвестная или непредвиденная ошибка. |
| clientInvalid | 1 | Клиенту не разрешено выполнять это действие. |
| paymentCancelled | 2 | <p>Пользователь отменил запрос на оплату.</p><p>Никаких действий не требуется, однако с точки зрения бизнес-логики вы можете предложить пользователю скидку или напомнить о покупке позже.</p> |
| paymentInvalid | 3 | Один из параметров платежа не был распознан стором. |
| paymentNotAllowed | 4 | <p>Пользователю не разрешено выполнять платежи. Возможные причины:</p><p></p><p>- Платежи не поддерживаются в стране пользователя.</p><p>- Пользователь является несовершеннолетним.</p> |
| storeProductNotAvailable | 5 | Запрошенный продукт отсутствует в App Store. Убедитесь, что продукт доступен для используемой страны. |
| cloudServicePermissionDenied | 6 | Пользователь не разрешил доступ к информации об облачном сервисе. |
| cloudServiceNetworkConnectionFailed | 7 | Устройству не удалось подключиться к сети. |
| cloudServiceRevoked | 8 | Пользователь отозвал разрешение на использование этого облачного сервиса. |
| privacyAcknowledgementRequired | 9 | Пользователь ещё не принял политику конфиденциальности стора. |
| unauthorizedRequestData | 10 | Запрос сформирован некорректно. |
| invalidOfferIdentifier | 11 | <p>Идентификатор оффера недействителен. Возможные причины:</p><p></p><p>- Оффер с таким идентификатором не настроен в App Store.</p><p>- Оффер был отозван.</p><p>- Идентификатор оффера указан с опечаткой.</p> |
| invalidSignature | 12 | Подпись в платёжной скидке недействительна. Убедитесь, что заполнено поле **In-app purchase Key ID** и загружен файл **In-App Purchase Private Key**. Подробнее см. в разделе [Настройка интеграции с App Store](app-store-connection-configuration). |
| missingOfferParams | 13 | <p>Проблема с интеграцией Adapty или с офферами.</p><p>Подробнее об их настройке см. в разделах [Настройка интеграции с App Store](app-store-connection-configuration) и [Офферы](offers).</p> |
| invalidOfferPrice | 14 | Указанная в сторе цена больше не действительна. Офферы всегда должны предоставлять скидку относительно базовой цены. |

## Кастомные коды Android \{#custom-android-codes\}

| Ошибка | Код | Описание |
|-----|----|-----------|
| adaptyNotInitialized | 20 | Необходимо правильно настроить Adapty SDK с помощью метода `Adapty.activate`. Узнайте, как это сделать [для React Native](sdk-installation-reactnative). |
| productNotFound | 22 | Запрошенный для покупки продукт недоступен в сторе. |
| invalidJson | 23 | JSON пейвола недействителен. Исправьте его в дашборде Adapty. Подробнее см. в разделе [Кастомизация пейвола с помощью Remote Config](customize-paywall-with-remote-config). |
| currentSubscriptionToUpdateNotFoundInHistory | 24 | Исходная подписка, которую необходимо продлить, не найдена. |
| pendingPurchase | 25 | Статус покупки — ожидание, а не выполнена. Подробнее см. на странице [Обработка отложенных транзакций](https://developer.android.com/google/play/billing/integrate#pending) в документации Android Developer. |
| billingServiceTimeout | 97 | Запрос достиг максимального таймаута до того, как Google Play успел ответить. Это может быть вызвано, например, задержкой при выполнении действия, запрошенного вызовом Play Billing Library. |
| featureNotSupported | 98 | Запрошенная функция не поддерживается Play Store на данном устройстве. |
| billingServiceDisconnected | 99 | Критическая ошибка: соединение клиентского приложения со службой Google Play Store через `BillingClient` было разорвано. |
| billingServiceUnavailable | 102 | Временная ошибка: служба Google Play Billing в данный момент недоступна. В большинстве случаев это означает проблему с сетевым соединением между клиентским устройством и серверами Google Play Billing. |
| billingUnavailable | 103 | <p>Ошибка выставления счёта на стороне пользователя в процессе покупки. Примеры ситуаций, когда это может произойти:</p><p></p><p>1\. Приложение Play Store на устройстве пользователя устарело.</p><p>2. Пользователь находится в неподдерживаемой стране.</p><p>3. Пользователь является корпоративным клиентом, и администратор заблокировал для него возможность совершать покупки.</p><p>4. Google Play не может списать средства с платёжного метода пользователя. Например, срок действия кредитной карты истёк.</p><p>5. Пользователь не авторизован в приложении Play Store.</p> |
| developerError | 105 | Критическая ошибка: некорректное использование API. |
| billingError | 106 | Критическая ошибка: внутренняя проблема на стороне Google Play. |
| itemAlreadyOwned | 107 | Расходуемая покупка уже была приобретена. |
| itemNotOwned | 108 | Запрошенное действие над товаром не выполнено, так как он не принадлежит пользователю. |

## Кастомные коды StoreKit \{#custom-storekit-codes\}

| Ошибка | Код | Описание |
|-----|----|-----------|
| noProductIDsFound | 1000 | <p>Ни один из продуктов пейвола недоступен в сторе.</p><p>Если вы столкнулись с этой ошибкой, выполните следующие шаги для её устранения:</p><p></p><p>1. Убедитесь, что все продукты добавлены в дашборд Adapty.</p><p>2. Убедитесь, что Bundle ID приложения совпадает с указанным в Apple Connect.</p><p>3. Проверьте, что идентификаторы продуктов из сторов совпадают с теми, что добавлены в дашборд. Обратите внимание: идентификаторы не должны содержать Bundle ID, если он не включён в идентификатор самого стора.</p><p>4. Убедитесь, что статус оплаты приложения активен в настройках налогов Apple. Убедитесь, что налоговые данные актуальны, а сертификаты действительны.</p><p>5. Проверьте, привязан ли банковский счёт к приложению — это необходимо для возможности монетизации.</p><p>6. Проверьте доступность продуктов во всех регионах. Также убедитесь, что ваши продукты находятся в статусе **"Ready to Submit"**.</p> |
| productRequestFailed | 1002 | <p>Не удалось получить список доступных продуктов. Возможная причина:</p><p></p><p>- Кэш ещё не создан, и при этом отсутствует подключение к интернету.</p> |
| cantMakePayments | 1003 | Встроенные покупки не разрешены на этом устройстве. |
| noPurchasesToRestore | 1004 | Google Play не нашёл покупки для восстановления. |
| cantReadReceipt | 1005 | <p>На устройстве нет действительного чека. Это может возникать при тестировании в песочнице.</p><p>Никаких действий не требуется, однако с точки зрения бизнес-логики вы можете предложить пользователю скидку или напомнить о покупке позже.</p> |
| productPurchaseFailed | 1006 | Покупка продукта не выполнена. |
| refreshReceiptFailed | 1010 | Чек не был получен. Применимо только к StoreKit 1. |
| receiveRestoredTransactionsFailed | 1011 | Восстановление покупок завершилось ошибкой. |

## Кастомные сетевые коды \{#custom-network-codes\}

| Ошибка | Код | Описание |
| :------------------- | :--- | :----------------------------------------------------------- |
| notActivated | 2002 | Необходимо правильно настроить Adapty SDK с помощью метода `Adapty.activate`. Узнайте, как это сделать [для React Native](sdk-installation-reactnative). |
| badRequest | 2003 | Некорректный запрос. |
| serverError | 2004 | Ошибка сервера. |
| networkFailed | 2005 | Сетевой запрос завершился ошибкой. |
| decodingFailed | 2006 | Ошибка декодирования ответа. |
| encodingFailed | 2009 | Ошибка кодирования запроса. |
| analyticsDisabled | 3000 | Обработка аналитических событий невозможна, так как вы отключили эту функцию. Подробнее см. в разделе [Интеграция аналитики](analytics-integration). |
| wrongParam | 3001 | Один или несколько параметров указаны некорректно: пустое значение там, где оно не допускается, неверный тип и т. д. |
| activateOnceError | 3005 | Метод `.activate` нельзя вызывать более одного раза. |
| profileWasChanged | 3006 | Профиль пользователя был изменён в ходе операции. |
| fetchTimeoutError | 3101 | Пейвол не удалось загрузить в отведённое время. Чтобы избежать этой ситуации, [настройте локальные резервные пейволы](fetch-paywalls-and-products). |
| operationInterrupted | 9000 | Операция была прервана системой. |