mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 18:00:02 +01:00
Add better application error handling for badges and token redemption.
This commit is contained in:
committed by
Greyson Parrelli
parent
2b6190bf34
commit
b8dc541fc5
@@ -2,4 +2,5 @@ package org.thoughtcrime.securesms.components.settings.app.subscription
|
||||
|
||||
class DonationExceptions {
|
||||
object TimedOutWaitingForTokenRedemption : Exception()
|
||||
object RedemptionFailed : Exception()
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.signal.donations.GooglePayApi
|
||||
import org.signal.donations.GooglePayPaymentSource
|
||||
import org.signal.donations.StripeApi
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.jobmanager.JobTracker
|
||||
import org.thoughtcrime.securesms.jobs.BoostReceiptRequestResponseJob
|
||||
import org.thoughtcrime.securesms.jobs.SubscriptionReceiptRequestResponseJob
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
@@ -114,15 +115,30 @@ class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFet
|
||||
val jobId = BoostReceiptRequestResponseJob.enqueueChain(paymentIntent)
|
||||
val countDownLatch = CountDownLatch(1)
|
||||
|
||||
var finalJobState: JobTracker.JobState? = null
|
||||
ApplicationDependencies.getJobManager().addListener(jobId) { _, jobState ->
|
||||
if (jobState.isComplete) {
|
||||
finalJobState = jobState
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (countDownLatch.await(10, TimeUnit.SECONDS)) {
|
||||
it.onComplete()
|
||||
when (finalJobState) {
|
||||
JobTracker.JobState.SUCCESS -> {
|
||||
Log.d(TAG, "Request response job chain succeeded.", true)
|
||||
it.onComplete()
|
||||
}
|
||||
JobTracker.JobState.FAILURE -> {
|
||||
Log.d(TAG, "Request response job chain failed permanently.", true)
|
||||
it.onError(DonationExceptions.RedemptionFailed)
|
||||
}
|
||||
else -> {
|
||||
Log.d(TAG, "Request response job chain ignored due to in-progress jobs.", true)
|
||||
it.onError(DonationExceptions.TimedOutWaitingForTokenRedemption)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
it.onError(DonationExceptions.TimedOutWaitingForTokenRedemption)
|
||||
}
|
||||
@@ -137,7 +153,7 @@ class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFet
|
||||
.flatMapCompletable { levelUpdateOperation ->
|
||||
val subscriber = SignalStore.donationsValues().requireSubscriber()
|
||||
|
||||
Log.d(TAG, "Attempting to set user subscription level to $subscriptionLevel")
|
||||
Log.d(TAG, "Attempting to set user subscription level to $subscriptionLevel", true)
|
||||
|
||||
ApplicationDependencies.getDonationsService().updateSubscriptionLevel(
|
||||
subscriber.subscriberId,
|
||||
@@ -145,27 +161,46 @@ class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFet
|
||||
subscriber.currencyCode,
|
||||
levelUpdateOperation.idempotencyKey.serialize()
|
||||
).flatMap(ServiceResponse<EmptyResponse>::flattenResult).ignoreElement().andThen {
|
||||
Log.d(TAG, "Successfully set user subscription to level $subscriptionLevel", true)
|
||||
SignalStore.donationsValues().clearUserManuallyCancelled()
|
||||
SignalStore.donationsValues().clearLevelOperation()
|
||||
LevelUpdate.updateProcessingState(false)
|
||||
it.onComplete()
|
||||
}.andThen {
|
||||
Log.d(TAG, "Enqueuing request response job chain.", true)
|
||||
val jobId = SubscriptionReceiptRequestResponseJob.enqueueSubscriptionContinuation()
|
||||
val countDownLatch = CountDownLatch(1)
|
||||
|
||||
var finalJobState: JobTracker.JobState? = null
|
||||
ApplicationDependencies.getJobManager().addListener(jobId) { _, jobState ->
|
||||
if (jobState.isComplete) {
|
||||
finalJobState = jobState
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (countDownLatch.await(10, TimeUnit.SECONDS)) {
|
||||
it.onComplete()
|
||||
when (finalJobState) {
|
||||
JobTracker.JobState.SUCCESS -> {
|
||||
Log.d(TAG, "Request response job chain succeeded.", true)
|
||||
it.onComplete()
|
||||
}
|
||||
JobTracker.JobState.FAILURE -> {
|
||||
Log.d(TAG, "Request response job chain failed permanently.", true)
|
||||
it.onError(DonationExceptions.RedemptionFailed)
|
||||
}
|
||||
else -> {
|
||||
Log.d(TAG, "Request response job chain ignored due to in-progress jobs.", true)
|
||||
it.onError(DonationExceptions.TimedOutWaitingForTokenRedemption)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Request response job timed out.", true)
|
||||
it.onError(DonationExceptions.TimedOutWaitingForTokenRedemption)
|
||||
}
|
||||
} catch (e: InterruptedException) {
|
||||
Log.w(TAG, "Request response interrupted.", e, true)
|
||||
it.onError(DonationExceptions.TimedOutWaitingForTokenRedemption)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,13 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsBottomSheetFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationEvent
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationExceptions
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.models.CurrencySelection
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.help.HelpFragment
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil.requireCoordinatorLayout
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
@@ -201,7 +203,7 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
|
||||
|
||||
private fun onPaymentError(throwable: Throwable?) {
|
||||
if (throwable is DonationExceptions.TimedOutWaitingForTokenRedemption) {
|
||||
Log.w(TAG, "Error occurred while redeeming token", throwable)
|
||||
Log.w(TAG, "Timed out while redeeming token", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__redemption_still_pending)
|
||||
.setMessage(R.string.DonationsErrors__you_might_not_see_your_badge_right_away)
|
||||
@@ -210,8 +212,19 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
.show()
|
||||
} else if (throwable is DonationExceptions.RedemptionFailed) {
|
||||
Log.w(TAG, "Error occurred while trying to redeem token", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__redemption_failed)
|
||||
.setMessage(R.string.DonationsErrors__please_contact_support)
|
||||
.setPositiveButton(R.string.Subscription__contact_support) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
requireActivity().finish()
|
||||
requireActivity().startActivity(AppSettingsActivity.help(requireContext(), HelpFragment.DONATION_INDEX))
|
||||
}
|
||||
.show()
|
||||
} else {
|
||||
Log.w(TAG, "Error occurred while processing payment", throwable)
|
||||
Log.w(TAG, "Error occurred while processing payment", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__payment_failed)
|
||||
.setMessage(R.string.DonationsErrors__your_payment)
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.DonationE
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.models.CurrencySelection
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.help.HelpFragment
|
||||
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
|
||||
import org.thoughtcrime.securesms.subscription.Subscription
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
@@ -235,7 +236,7 @@ class SubscribeFragment : DSLSettingsFragment(
|
||||
|
||||
private fun onPaymentError(throwable: Throwable?) {
|
||||
if (throwable is DonationExceptions.TimedOutWaitingForTokenRedemption) {
|
||||
Log.w(TAG, "Error occurred while redeeming token", throwable)
|
||||
Log.w(TAG, "Timeout occurred while redeeming token", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__redemption_still_pending)
|
||||
.setMessage(R.string.DonationsErrors__you_might_not_see_your_badge_right_away)
|
||||
@@ -245,8 +246,19 @@ class SubscribeFragment : DSLSettingsFragment(
|
||||
requireActivity().startActivity(AppSettingsActivity.subscriptions(requireContext()))
|
||||
}
|
||||
.show()
|
||||
} else if (throwable is DonationExceptions.RedemptionFailed) {
|
||||
Log.w(TAG, "Error occurred while trying to redeem token", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__redemption_failed)
|
||||
.setMessage(R.string.DonationsErrors__please_contact_support)
|
||||
.setPositiveButton(R.string.Subscription__contact_support) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
requireActivity().finish()
|
||||
requireActivity().startActivity(AppSettingsActivity.help(requireContext(), HelpFragment.DONATION_INDEX))
|
||||
}
|
||||
.show()
|
||||
} else {
|
||||
Log.w(TAG, "Error occurred while processing payment", throwable)
|
||||
Log.w(TAG, "Error occurred while processing payment", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__payment_failed)
|
||||
.setMessage(R.string.DonationsErrors__your_payment)
|
||||
@@ -267,7 +279,7 @@ class SubscribeFragment : DSLSettingsFragment(
|
||||
}
|
||||
|
||||
private fun onSubscriptionFailedToCancel(throwable: Throwable) {
|
||||
Log.w(TAG, "Failed to cancel subscription", throwable)
|
||||
Log.w(TAG, "Failed to cancel subscription", throwable, true)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.DonationsErrors__failed_to_cancel_subscription)
|
||||
.setMessage(R.string.DonationsErrors__subscription_cancellation_requires_an_internet_connection)
|
||||
|
||||
Reference in New Issue
Block a user