From dce3dca9cc88c688826c1874e0a44b96e8f44f8f Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Fri, 6 Dec 2024 09:49:23 -0400 Subject: [PATCH] Self-heal payment state transfer if onAdded fails to update as expected. --- .../securesms/jobs/InAppPaymentOneTimeContextJob.kt | 9 ++++++++- .../securesms/jobs/InAppPaymentRecurringContextJob.kt | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentOneTimeContextJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentOneTimeContextJob.kt index b1443d1afd..f12220adcd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentOneTimeContextJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentOneTimeContextJob.kt @@ -99,6 +99,7 @@ class InAppPaymentOneTimeContextJob private constructor( override fun onAdded() { val inAppPayment = SignalDatabase.inAppPayments.getById(inAppPaymentId) + info("Added context job for payment with state ${inAppPayment?.state}") if (inAppPayment?.state == InAppPaymentTable.State.CREATED) { SignalDatabase.inAppPayments.update( inAppPayment.copy( @@ -184,7 +185,12 @@ class InAppPaymentOneTimeContextJob private constructor( if (inAppPayment.state != InAppPaymentTable.State.PENDING) { warning("Invalid state: ${inAppPayment.state} but expected PENDING") - throw IOException("InAppPayment is in an invalid state") + + if (inAppPayment.state == InAppPaymentTable.State.CREATED) { + warning("onAdded failed to update payment state to PENDING. Updating now as long as the payment is valid otherwise.") + } else { + throw IOException("InAppPayment is in an invalid state: ${inAppPayment.state}") + } } if (inAppPayment.data.redemption == null) { @@ -207,6 +213,7 @@ class InAppPaymentOneTimeContextJob private constructor( } ?: InAppPaymentsRepository.generateRequestCredential() val updatedPayment = inAppPayment.copy( + state = InAppPaymentTable.State.PENDING, data = inAppPayment.data.copy( redemption = inAppPayment.data.redemption.copy( stage = InAppPaymentData.RedemptionState.Stage.CONVERSION_STARTED, diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRecurringContextJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRecurringContextJob.kt index 3081292233..c7c62d31d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRecurringContextJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRecurringContextJob.kt @@ -185,7 +185,12 @@ class InAppPaymentRecurringContextJob private constructor( if (inAppPayment.state != InAppPaymentTable.State.PENDING) { warning("Unexpected state. Got ${inAppPayment.state} but expected PENDING") - throw IOException("InAppPayment in unexpected state.") + + if (inAppPayment.state == InAppPaymentTable.State.CREATED) { + warning("onAdded failed to update payment state to PENDING. Updating now as long as the payment is valid otherwise.") + } else { + throw IOException("InAppPayment is in an invalid state: ${inAppPayment.state}") + } } if (!inAppPayment.type.recurring) { @@ -211,6 +216,7 @@ class InAppPaymentRecurringContextJob private constructor( return if (inAppPayment.data.redemption.receiptCredentialRequestContext == null) { val requestContext = InAppPaymentsRepository.generateRequestCredential() val updatedPayment = inAppPayment.copy( + state = InAppPaymentTable.State.PENDING, data = inAppPayment.data.copy( redemption = inAppPayment.data.redemption.copy( stage = InAppPaymentData.RedemptionState.Stage.CONVERSION_STARTED,