[EXTERNAL] fix(google): guard showInAppMessages against BillingClient runtime crashes#3367
Merged
MonikaMateska merged 1 commit intoApr 20, 2026
Conversation
Member
|
Hi @matteinn, thanks for the fix! We're taking a look. |
6aaaa4e
into
RevenueCat:external/matteinn/fix/#3367-billingwrapper-npe
3 checks passed
4 tasks
github-merge-queue Bot
pushed a commit
that referenced
this pull request
Apr 20, 2026
… runtime crashes (#3367) by @matteinn (#3368) <!-- Thank you for contributing to Purchases! Before pressing the "Create Pull Request" button, please provide the following: --> ### Checklist - [x] If applicable, unit tests - [ ] If applicable, create follow-up issues for `purchases-ios` and hybrids ### Motivation <!-- Why is this change required? What problem does it solve? --> <!-- Please link to issues following this format: Resolves #999999 --> This PR hardens `showInAppMessagesIfNeeded` against a remaining Play Billing crash path. Resolves #3273, which has not been fully solved by a previous [tentative](#3274). ### Description <!-- Describe your changes in detail --> <!-- Please describe in detail how you tested your changes --> Even after lifecycle/window attachment checks, `BillingClient.showInAppMessages(...)` can still throw a `RuntimeException` (including `NullPointerException`) due to an internal race in Play Billing. This is a defensive boundary around third-party BillingClient behavior: it complements previous activity/window checks by handling exceptions that can still occur between pre-checks and BillingClient’s internal view/token access. Here's exactly what changed: - Wrapped the `showInAppMessages(...)` invocation in `BillingWrapper` with a try/catch - On exception, log the error and skip showing the in-app message instead of crashing the app - Added new log string: BILLING_INAPP_MESSAGE_SHOW_EXCEPTION - Added a regression unit test that simulates `showInAppMessages(...)` throwing a `NullPointerException` and verifies that there are no crash and that the error is logged <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Small defensive change limited to in-app message display: it only adds exception handling and logging, plus a unit test, with minimal behavior impact beyond avoiding a crash. > > **Overview** > Prevents app crashes when Google Play Billing’s `BillingClient.showInAppMessages` throws a `RuntimeException` despite lifecycle/window checks, by wrapping the call in a `try/catch` and logging a new `BILLING_INAPP_MESSAGE_SHOW_EXCEPTION` error instead of propagating the crash. > > Adds a regression test that forces `showInAppMessages` to throw (e.g., `NullPointerException`) and asserts the wrapper logs the error and continues without crashing. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit fc5cd08. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- Thank you for contributing to Purchases! Before pressing the "Create Pull Request" button, please provide the following: --> ### Checklist - [ ] If applicable, unit tests - [ ] If applicable, create follow-up issues for `purchases-ios` and hybrids ### Motivation <!-- Why is this change required? What problem does it solve? --> <!-- Please link to issues following this format: Resolves #999999 --> ### Description <!-- Describe your changes in detail --> <!-- Please describe in detail how you tested your changes --> --------- Co-authored-by: Matteo Innocenti <matteo@appstyx.com>
matteinn
pushed a commit
to matteinn/purchases-android
that referenced
this pull request
Apr 28, 2026
**This is an automatic release.** ## RevenueCat SDK ### 🐞 Bugfixes * fix: move Google BillingClient connection off the main thread (RevenueCat#3369) via Toni Rico (@tonidero) * [EXTERNAL] fix(google): guard showInAppMessages against BillingClient runtime crashes (RevenueCat#3367) by @matteinn (RevenueCat#3368) via Monika Mateska (@MonikaMateska) ## RevenueCatUI SDK ### Paywallv2 #### 🐞 Bugfixes * Add Workflows network layer (RevenueCat#3300) via Cesar de la Vega (@vegaro) ### 🔄 Other Changes * Fix `revenuecat.useWorkflowsEndpoint` compiler flag (RevenueCat#3374) via Cesar de la Vega (@vegaro) * Create paywall from workflow response. Add `USE_WORKFLOWS_ENDPOINT` BuildConfig (RevenueCat#3350) via Cesar de la Vega (@vegaro) * Refactor: Remove unnecessary lint suppressions (RevenueCat#3373) via cursor[bot] (@cursor[bot]) * Bump fastlane-plugin-revenuecat_internal from `a1eed48` to `b822f01` (RevenueCat#3371) via dependabot[bot] (@dependabot[bot]) * Bump fastlane from 2.232.2 to 2.233.0 (RevenueCat#3370) via dependabot[bot] (@dependabot[bot]) * Attempt to fix `AssertionError` "ms is denormalized" in `QueryPurchasesUseCaseTest` (RevenueCat#3361) via Cesar de la Vega (@vegaro) * Update baseline profiles (RevenueCat#3296) via Jaewoong Eum (@skydoves) * fix: reduce precision for flaky HeaderDirectHeroImage snapshot (RevenueCat#3362) via Cesar de la Vega (@vegaro) * Fix test failures reported twice (RevenueCat#3360) via Cesar de la Vega (@vegaro) * refactor: extract `updateStateFromOffering` in `PaywallViewModel` (RevenueCat#3359) via Cesar de la Vega (@vegaro) * [Fix] Include parent tabs component_name in tab-control switch interaction events (RevenueCat#3358) via Monika Mateska (@MonikaMateska) * Refactor: Remove unnecessary lint suppressions (RevenueCat#3348) via cursor[bot] (@cursor[bot]) * fix: always upload CI test results even when tests fail (RevenueCat#3357) via Cesar de la Vega (@vegaro) * refactor: extract `RevenueCatDialogScaffold` (RevenueCat#3355) via Cesar de la Vega (@vegaro) * Fix Slack notifications for nightly integration tests (RevenueCat#3354) via Toni Rico (@tonidero) * UI events for paywall component interactions (RevenueCat#3287) via Monika Mateska (@MonikaMateska) * Bump fastlane-plugin-revenuecat_internal from `20911d1` to `a1eed48` (RevenueCat#3351) via dependabot[bot] (@dependabot[bot]) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Primarily a version bump and release automation updates (docs deploy/redirect and changelog); no functional library code changes beyond updating embedded version constants. > > **Overview** > Cuts the `10.2.1` release by updating version references across the repo (Gradle `VERSION_NAME`, internal `frameworkVersion`, sample/test app dependency pins, and `.version`). > > Updates the docs release pipeline and website redirect to publish and point at `10.2.1`, and refreshes `CHANGELOG.md`/`CHANGELOG.latest.md` with the 10.2.1 release notes. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a0a325b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist
purchases-iosand hybridsMotivation
This PR hardens
showInAppMessagesIfNeededagainst a remaining Play Billing crash path.Resolves #3273, which has not been fully solved by a previous tentative.
Description
Even after lifecycle/window attachment checks,
BillingClient.showInAppMessages(...)can still throw aRuntimeException(includingNullPointerException) due to an internal race in Play Billing.This is a defensive boundary around third-party BillingClient behavior: it complements previous activity/window checks by handling exceptions that can still occur between pre-checks and BillingClient’s internal view/token access.
Here's exactly what changed:
showInAppMessages(...)invocation inBillingWrapperwith a try/catchshowInAppMessages(...)throwing aNullPointerExceptionand verifies that there are no crash and that the error is loggedNote
Low Risk
Low risk defensive change that only adds exception handling and logging around a third-party call; behavior changes only when Play Billing throws unexpectedly.
Overview
Prevents a remaining Play Billing crash path by wrapping
BillingClient.showInAppMessages(...)inBillingWrapper.showInAppMessagesIfNeededwith atry/catchand logging an error instead of crashing.Adds a new log string (
BILLING_INAPP_MESSAGE_SHOW_EXCEPTION) and a regression unit test that simulatesshowInAppMessagesthrowing (e.g.,NullPointerException) and asserts it is logged and does not crash.Reviewed by Cursor Bugbot for commit 5e8afd5. Bugbot is set up for automated code reviews on this repo. Configure here.