diff --git a/purchases/src/main/kotlin/com/revenuecat/purchases/Dispatcher.kt b/purchases/src/main/kotlin/com/revenuecat/purchases/Dispatcher.kt index 9f36ab052e..25411e8308 100644 --- a/purchases/src/main/kotlin/com/revenuecat/purchases/Dispatcher.kt +++ b/purchases/src/main/kotlin/com/revenuecat/purchases/Dispatcher.kt @@ -27,6 +27,9 @@ internal open class Dispatcher( onError(e.toPurchasesError()) } catch (e: IOException) { onError(e.toPurchasesError()) + } catch (e: SecurityException) { + // This can happen if a user disables the INTERNET permission. + onError(e.toPurchasesError()) } } } diff --git a/purchases/src/main/kotlin/com/revenuecat/purchases/errors.kt b/purchases/src/main/kotlin/com/revenuecat/purchases/errors.kt index 5ed5b9d3f7..31eea43a67 100644 --- a/purchases/src/main/kotlin/com/revenuecat/purchases/errors.kt +++ b/purchases/src/main/kotlin/com/revenuecat/purchases/errors.kt @@ -39,6 +39,7 @@ enum class PurchasesErrorCode(val description: String) { InvalidAppUserIdError("The app user id is not valid."), OperationAlreadyInProgressError("The operation is already in progress."), UnknownBackendError("There was an unknown backend error."), + InsufficientPermissionsError("App does not have sufficient permissions to make purchases.") } internal enum class BackendErrorCode(val value: Int) { @@ -67,6 +68,8 @@ internal enum class BackendErrorCode(val value: Int) { internal fun Exception.toPurchasesError(): PurchasesError { if (this is JSONException || this is IOException) { return PurchasesError(PurchasesErrorCode.NetworkError, localizedMessage) + } else if (this is SecurityException) { + return PurchasesError(PurchasesErrorCode.InsufficientPermissionsError, localizedMessage) } return PurchasesError(PurchasesErrorCode.UnknownError, localizedMessage) } diff --git a/purchases/src/test/java/com/revenuecat/purchases/DispatcherTest.kt b/purchases/src/test/java/com/revenuecat/purchases/DispatcherTest.kt index 2d9311a103..38dac483b5 100644 --- a/purchases/src/test/java/com/revenuecat/purchases/DispatcherTest.kt +++ b/purchases/src/test/java/com/revenuecat/purchases/DispatcherTest.kt @@ -17,6 +17,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.robolectric.annotation.Config import java.util.concurrent.ExecutorService +import java.util.concurrent.atomic.AtomicReference @RunWith(AndroidJUnit4::class) @Config(manifest = Config.NONE) @@ -99,4 +100,23 @@ class DispatcherTest { executorService.shutdownNow() } } + + @Test + fun securityExceptionsAreCorrectlyConvertedToPurchaseErrors() { + val errorHolder = AtomicReference() + + val call = object : Dispatcher.AsyncCall() { + override fun call(): HTTPClient.Result { + throw SecurityException("missing permissoins") + } + + override fun onError(error: PurchasesError) { + errorHolder.set(error) + } + } + + call.run() + + assertThat(errorHolder.get().code).isEqualTo(PurchasesErrorCode.InsufficientPermissionsError) + } }