Error Handling
Success This section assumes you've followed our Quickstart section of our Getting Started guide to install and configure our SDK.
Error Handling
If the completion callbacks or listeners on asynchronous methods receive an error argument that is not nil, an error has occurred.
With the exception of NetworkError
, PurchaseCancelledError
or StoreProblemError
, retrying a failed operation with the same arguments won't succeed. For failed purchases, assume the user wasn't charged, unless a StoreProblemError
occurred - in which case the user may or may not have been charged.
iOS Errors
On iOS, when an error has occurred the completion callback will receive a RevenueCat.ErrorCode
object.
When investigating or logging errors, review the errorUserInfo
dictionary, paying attention to the following keys:
rc_code_name
contains a cross-platform error name string that can be used for identifying the error.NSDebugDescriptionErrorKey
contains a description of the error. This description is meant for the developer.
Examples
- Swift
- Objective-C
if let error = error as? RevenueCat.ErrorCode {
print(error.errorCode)
print(error.errorUserInfo)
switch error {
case .purchaseNotAllowedError:
showAlert("Purchases not allowed on this device.")
case .purchaseInvalidError:
showAlert("Purchase invalid, check payment source.")
default: break
}
} else {
// Error is a different type
}
if (error) {
// log error details
NSLog(@"RCError: %@", [error.userInfo objectForKey:RCReadableErrorCodeKey]);
NSLog(@"Message: %@", error.localizedDescription);
NSLog(@"Underlying Error: %@", [error.userInfo objectForKey:NSUnderlyingErrorKey]);
switch ([error code]) {
case RCNetworkError:
showError(@"Network error, check your connection and try again.");
case RCPurchaseNotAllowedError:
showError(@"Purchases not allowed on this device.");
case RCPurchaseInvalidError:
showError(@"Purchase invalid, check payment source.");
default:
break;
}
}
Android Errors
On Android, when an error has occurred, the onError
listener will receive a PurchasesError
object.
When investigating or logging errors, review the properties of PurchasesError
:
code
contains thePurchasesErrorCode
that can be used for identifying the error.message
contains a description of the error. This description is meant for the developer.underlyingErrorMessage
contains a description of the underlying error that caused the error in question, if an underlying error is present.
Examples
- Kotlin
with(error) {
// log error details
print("Error: $code")
print("Message: $message")
print("Underlying Error: $underlyingErrorMessage")
when (code) {
PurchasesErrorCode.PurchaseNotAllowedError -> {
showAlert("Purchases not allowed on this device.")
}
PurchasesErrorCode.PurchaseInvalidError -> {
showAlert("Purchase invalid, check payment source.")
}
else -> {}
}
}
Legend
When debugging errors, it's important to consider whether the error was thrown by RevenueCat, Apple, or Google. This can help you pinpoint where to look for a resolution.
Icon | Description |
---|---|
😿 | Error generated from RevenueCat |
🍎 | Error generated from Apple |
🤖 | Error generated from Google |
📦 | Error generated from Amazon |
Error codes common to all methods
😿 INVALID_APP_USER_ID
Problem: Indicates the App User Id is set to an invalid value.
Resolution: Make sure you're not sending a string over 100 characters or a blocked app user Id.
😿 🍎 🤖 📦 INVALID_CREDENTIALS
Problem: Indicates the application has been configured with an invalid credentials.
Resolution: If this error occurs before a purchase, ensure you're using the correct API Key from the RevenueCat dashboard. If this error happens during the purchase flow, make sure your Play Store Credentials and/or App Store Shared Secret and/or Amazon Appstore Credentials are configured correctly in the RevenueCat dashboard.
😿 INVALID_SUBSCRIBER_ATTRIBUTES
Problem: Indicates attributes for a Customer were unable to be saved.
Resolution: Make sure that there are no formatting issues when setting attributes.
😿 NETWORK_ERROR
Problem: Indicates a network error occurred during the operation.
Resolution: Make sure the device has an internet connection and try again. If you are testing in sandbox, make sure your outgoing connections is turned on. You can find this in XCode under signing & capabilities > App Sandbox > Outgoing connections (Client).
😿 OFFLINE_CONNECTION_ERROR
Problem: Indicates the device was offline when attempting a network request.
Resolution: Make sure the device has an internet connection and try again.
😿 OPERATION_ALREADY_IN_PROGRESS
Problem:
Indicates an identical operation is already in progress. For example, making two identical purchase attempts at the same time.
Resolution: Wait for the original operation to complete.
🍎 🤖 📦 STORE_PROBLEM
Problem: This error is forwarded from Apple/Google/Amazon and indicates there was a problem connecting to the App Store, Play Store, or Amazon Appstore.
The problems that will trigger this on iOS:
- Apple server is down (more common in sandbox than production)
- SKErrorUnknown
- SKErrorCloudServiceNetworkConnectionFailed
- SKErrorCloudServiceRevoked
- An SCA purchase flow was initiated.
The problems that will trigger this on Android:
- Google server is down
- Google Play Developer API Quota exceeded
- Invalid Android package name in the RevenueCat dashboard
- Google Billing Client SERVICE_TIMEOUT error
Resolution: If everything was working while testing, you shouldn't have to do anything to handle this error in production. RevenueCat will automatically retry any purchase failures so no data is lost.
If this occurs while testing in sandbox you can try:
- Repeating the operation later.
- Create a new sandbox user on iOS.
🤷 SIGNATURE_VERIFICATION_FAILED
Problem: Indicates that the SDK detected a request was tampered.
Resolution:
- Ensure that a proxy is not modifying responses from our API.
- See the docs for more information.
😿 UNEXPECTED_BACKEND_RESPONSE_ERROR
Problem: Indicates the SDK received an unexpected response from the server.
iOS sub error codes:
loginResponseDecoding
: Unable to decode response returned from login.postOfferIdBadResponse
: Unable to decode response returned from posting offer for signing.postOfferIdMissingOffersInResponse
: Missing offers from response returned from posting offer for signing.postOfferIdSignature
: Signature error encountered in response returned from posting offer for signing.getOfferUnexpectedResponse
: Unknown error encountered while getting offerings.customerInfoNil
: Unable to instantiate a CustomerInfoResponse, CustomerInfo in response was nil.customerInfoResponseParsing
: Unable to instantiate a CustomerInfoResponse due to malformed json.
Resolution: Report the error with the full error object.