Skip to content

fix(google): surface query product diagnostics#138

Merged
hyochan merged 7 commits into
mainfrom
codex/fix-google-query-product-diagnostics
May 7, 2026
Merged

fix(google): surface query product diagnostics#138
hyochan merged 7 commits into
mainfrom
codex/fix-google-query-product-diagnostics

Conversation

@hyochan
Copy link
Copy Markdown
Member

@hyochan hyochan commented May 7, 2026

Summary

  • preserve Android QueryProduct BillingResult diagnostics in openiap-google Play and Horizon query paths
  • pass QueryProduct diagnostic JSON through the React Native Android and MAUI Android bridges
  • expose QueryProduct diagnostics on the shared PurchaseError schema and synced SDK generated types
  • preserve partial React Native Android ProductQueryType.All results while querying InApp/Subs concurrently
  • document the Android QueryProduct diagnostics and keep release notes on openiap-google 2.1.4
  • align the root version manifest by removing the framework-library maui key and moving MAUI release versioning to OpenIap.Maui.csproj

Issue

Closes #137

Notes

  • openiap-versions.json is intentionally changed as a one-time manifest cleanup requested in review; it now tracks only spec, google, and apple
  • MAUI package versioning now comes from libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj, and release-maui.yml updates only that package metadata
  • packages/kit/convex/_generated/api.d.ts is included because the generated Convex API now references utils/currency

Validation

  • git diff --check
  • packages/gql: bun run generate
  • packages/gql: bun run test
  • packages/google: ./gradlew :openiap:compilePlayDebugKotlin
  • packages/google: ./gradlew :openiap:compileHorizonDebugKotlin
  • packages/google: ./gradlew :openiap:testPlayDebugUnitTest --tests dev.hyo.openiap.OpenIapErrorTest
  • packages/apple: swift test
  • libraries/react-native-iap: yarn typecheck:lib
  • libraries/react-native-iap/example/android: ./gradlew :react-native-iap:compileDebugKotlin
  • libraries/react-native-iap/example/android: ./gradlew :react-native-iap:testDebugUnitTest --tests com.margelo.nitro.iap.ProductQueryHelpersTest
  • libraries/expo-iap: bun run lint:tsc
  • libraries/flutter_inapp_purchase: flutter test
  • libraries/kmp-iap: ./gradlew :library:compileKotlinMetadata
  • libraries/maui-iap/android: :openiap:compileDebugKotlin via packages/google/gradlew
  • dotnet build libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj -p:TargetFrameworks=net9.0
  • packages/docs: bun run typecheck
  • bun audit:docs (advisory warnings only; no hard failures)
  • release-maui.yml YAML parse check
  • commit hook: flutter analyze, kmp debug Android compile, docs typecheck/format, kit lint/prettier/tests/smoke

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced error reporting for Android product query failures with additional diagnostic details including response codes, requested product IDs, product type, and product list status indicators.
  • Documentation

    • Updated error documentation to describe diagnostic fields now available in Android QueryProduct errors from the latest SDK version.

Add structured QueryProduct diagnostics for Android product query failures, including Billing response code, debug message, queried product IDs, product type, and empty-result state.

Propagate the diagnostics through React Native and MAUI bridges, and document the skipped openiap-google 2.1.3 release as openiap-google 2.1.4.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack

Warning

Rate limit exceeded

@hyochan has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minute and 42 seconds before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aebca652-7c38-45c2-8fe5-220c29d3a7a4

📥 Commits

Reviewing files that changed from the base of the PR and between 3cbc913 and 4a8f4c4.

⛔ Files ignored due to path filters (7)
  • packages/gql/src/generated/Types.cs is excluded by !**/generated/**
  • packages/gql/src/generated/Types.kt is excluded by !**/generated/**
  • packages/gql/src/generated/Types.swift is excluded by !**/generated/**
  • packages/gql/src/generated/types.dart is excluded by !**/generated/**
  • packages/gql/src/generated/types.gd is excluded by !**/generated/**
  • packages/gql/src/generated/types.ts is excluded by !**/generated/**
  • packages/kit/convex/_generated/api.d.ts is excluded by !**/_generated/**
📒 Files selected for processing (26)
  • .github/workflows/release-maui.yml
  • CLAUDE.md
  • knowledge/internal/04-platform-packages.md
  • knowledge/internal/06-git-deployment.md
  • libraries/expo-iap/src/types.ts
  • libraries/flutter_inapp_purchase/lib/types.dart
  • libraries/godot-iap/addons/godot-iap/types.gd
  • libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt
  • libraries/maui-iap/CLAUDE.md
  • libraries/maui-iap/src/OpenIap.Maui/Types.cs
  • libraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt
  • libraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/ProductQueryHelpers.kt
  • libraries/react-native-iap/android/src/test/java/com/margelo/nitro/iap/ProductQueryHelpersTest.kt
  • libraries/react-native-iap/src/types.ts
  • openiap-versions.json
  • packages/apple/Sources/Models/Types.swift
  • packages/docs/openiap-versions.json
  • packages/docs/src/pages/docs/errors.tsx
  • packages/google/openiap/src/horizon/java/dev/hyo/openiap/OpenIapModule.kt
  • packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt
  • packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
  • packages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.kt
  • packages/google/openiap/src/play/java/dev/hyo/openiap/helpers/ProductManager.kt
  • packages/google/openiap/src/test/java/dev/hyo/openiap/OpenIapErrorTest.kt
  • packages/gql/src/error.graphql
  • packages/gql/src/generated-purchase-error.test.ts
📝 Walkthrough

Walkthrough

This PR enriches Android product-query error handling by threading structured billing diagnostics (response code, debug message, product IDs, type, and empty-list indicators) through the error pipeline from the Billing Client API through platform layers to JavaScript consumers, addressing diagnostic gaps described in issue #137.

Changes

Enriched Product Query Error Diagnostics

Layer / File(s) Summary
Data Types and Contracts
packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt, libraries/react-native-iap/src/utils/error.ts, libraries/react-native-iap/src/utils/errorMapping.ts
OpenIapError sealed class adds public properties responseCode, productIds, productType, isEmptyProductList and extends toJSON() to serialize them. QueryProduct gains a factory function to construct QueryProductFailure. IapError and PurchaseError interfaces updated with the new optional fields.
Android Error Construction
packages/google/openiap/src/play/java/dev/hyo/openiap/helpers/ProductManager.kt, packages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.kt, packages/google/openiap/src/horizon/java/dev/hyo/openiap/OpenIapModule.kt
When product queries fail or return empty results, ProductManager and both Horizon/Play OpenIapModule variants now construct QueryProduct errors with explicit billing response code, debug message, requested product IDs, product type, and empty-list indicator instead of generic error codes.
Cross-Platform Error Encoding
libraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt, libraries/maui-iap/android/openiap/src/main/java/dev/hyo/openiap/maui/OpenIapMauiModule.kt
toErrorJson and encodeError now extract diagnostic fields from error.toJSON() and serialize them via JSONObject or direct map inclusion, replacing manual string concatenation.
Error Propagation to JavaScript
libraries/react-native-iap/src/index.ts, libraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt, libraries/react-native-iap/src/utils/errorMapping.ts
Purchase error listener uses shared toErrorResult helper. fetchProducts wraps product queries in explicit try/catch and normalizes errors via createPurchaseError. Error mapping functions pass through productIds, productType, and isEmptyProductList to the final PurchaseError.
Testing and Documentation
packages/google/openiap/src/test/java/dev/hyo/openiap/OpenIapErrorTest.kt, packages/docs/src/pages/docs/errors.tsx, packages/docs/src/pages/docs/updates/releases.tsx
New unit test verifies QueryProductFailure construction and toJSON() output. Documentation note added under "Common Error Codes" explaining Android diagnostic availability in openiap-google 2.1.4+. Release notes updated to reference openiap-google 2.1.4.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

cross-platform

Poem

🐰 From Billing's depths, diagnostics bloom,
Response codes chase away the gloom,
ProductIds light the query's way,
Error messages now have much to say! 🎯

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(google): surface query product diagnostics' accurately describes the main change—surfacing detailed diagnostic information for Android QueryProduct failures.
Linked Issues check ✅ Passed The PR fully addresses issue #137 objectives: QueryProduct errors now include BillingResult.responseCode, debugMessage, productIds, productType, and isEmptyProductList across Android Play/Horizon modules and bridging layers.
Out of Scope Changes check ✅ Passed All changes are directly related to surfacing QueryProduct diagnostics (issue #137). Documentation updates correctly describe the new diagnostic fields, and the MAUI module changes align with existing patterns.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-google-query-product-diagnostics

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hyochan hyochan added maui maui library react-native-iap react-native-iap library 🐛 bug Something isn't working 📖 documentation Improvements or additions to documentation 🤖 android Related to android labels May 7, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances error reporting for Android QueryProduct failures by including detailed diagnostics such as responseCode, debugMessage, productIds, productType, and isEmptyProductList. These changes are implemented across the core Google package, React Native and MAUI libraries, and documentation. Key improvements include structured JSON error serialization using JSONObject and updated TypeScript interfaces to support the new fields. I have no feedback to provide as there were no review comments to assess.

@hyochan hyochan marked this pull request as ready for review May 7, 2026 16:09
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@libraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt`:
- Around line 338-382: The ProductQueryType.All branch currently wraps both
openIap.fetchProducts calls in a single try-catch causing any per-kind
OpenIAPError to abort the whole query; change this to isolate each kind's fetch
(ProductQueryType.InApp and ProductQueryType.Subs) with per-kind runCatching/try
and default to an empty list on failure, collect any thrown OpenIAPError(s) but
continue, merge results into byId and return products in skusList order, and
only if the merged result is empty rethrow an OpenIapException(created via
toErrorJson from the captured error or a combined error) so partial successes
are preserved (update handling around openIap.fetchProducts,
ProductQueryType.All, OpenIAPError and OpenIapException accordingly).

In `@packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt`:
- Around line 17-30: The base OpenIapError.toJSON currently emits responseCode,
productIds, productType and isEmptyProductList for every error subtype; remove
those four diagnostic fields from the OpenIapError.toJSON map so only generic
fields (code, message, platform, debugMessage) are returned, and add/override
toJSON in QueryProductFailure to merge the base map with the diagnostic fields
(responseCode, productIds, productType, isEmptyProductList) so only
QueryProductFailure serializes them; refer to OpenIapError.toJSON and the
QueryProductFailure class when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 687b01b4-6bff-4efc-b233-b90ef84f3122

📥 Commits

Reviewing files that changed from the base of the PR and between 6bb94e3 and 3cbc913.

📒 Files selected for processing (12)
  • libraries/maui-iap/android/openiap/src/main/java/dev/hyo/openiap/maui/OpenIapMauiModule.kt
  • libraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt
  • libraries/react-native-iap/src/index.ts
  • libraries/react-native-iap/src/utils/error.ts
  • libraries/react-native-iap/src/utils/errorMapping.ts
  • packages/docs/src/pages/docs/errors.tsx
  • packages/docs/src/pages/docs/updates/releases.tsx
  • packages/google/openiap/src/horizon/java/dev/hyo/openiap/OpenIapModule.kt
  • packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt
  • packages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.kt
  • packages/google/openiap/src/play/java/dev/hyo/openiap/helpers/ProductManager.kt
  • packages/google/openiap/src/test/java/dev/hyo/openiap/OpenIapErrorTest.kt

Comment thread packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt Outdated
@hyochan
Copy link
Copy Markdown
Member Author

hyochan commented May 7, 2026

@coderabbitai review

@hyochan
Copy link
Copy Markdown
Member Author

hyochan commented May 7, 2026

/gemini review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@hyochan hyochan requested a review from Copilot May 7, 2026 16:37
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces enhanced error diagnostics for Android QueryProduct failures, adding detailed fields such as responseCode, productIds, and productType to error objects across the Google, MAUI, and React Native libraries. It also refactors the React Native Android implementation to use a new collectAllQueryProducts helper and updates documentation to enforce a policy where openiap-versions.json only tracks core platform versions. Review feedback recommends parallelizing the sequential network requests in the new Android helper using coroutines to improve performance and highlights a discrepancy between the PR description and the manual removal of the maui key from the version manifest.

Comment thread openiap-versions.json
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Android QueryProduct failure observability by carrying Google Billing diagnostics through the openiap-google (Play + Horizon) query paths, then plumbing those diagnostics through the React Native and MAUI Android bridges, and documenting the new fields.

Changes:

  • Add a diagnostic-carrying QueryProduct error variant and populate it from BillingResult details in Play/Horizon query flows.
  • Propagate the new diagnostic fields through the React Native error types + Android bridge (including new helper + tests).
  • Update docs/release notes and clarify version-manifest ownership/scope; adjust MAUI release workflow to read the NuGet version from the csproj.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/kit/convex/_generated/api.d.ts Regenerated Convex API typings to include utils/currency.
packages/google/openiap/src/test/java/dev/hyo/openiap/OpenIapErrorTest.kt Adds tests asserting QueryProduct diagnostic serialization behavior.
packages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.kt Surfaces BillingResult diagnostics when product queries fail in Play flow.
packages/google/openiap/src/play/java/dev/hyo/openiap/helpers/ProductManager.kt Converts Play query failures to OpenIapError.QueryProduct(...) with diagnostics.
packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt Makes toJSON() overridable and adds diagnostic-carrying QueryProduct failure type.
packages/google/openiap/src/horizon/java/dev/hyo/openiap/OpenIapModule.kt Surfaces BillingResult diagnostics when product queries fail in Horizon flow.
packages/docs/src/pages/docs/updates/releases.tsx Updates release notes entry to openiap-google 2.1.4 and mentions new diagnostics.
packages/docs/src/pages/docs/errors.tsx Documents Android QueryProduct diagnostics fields and usage guidance.
packages/docs/openiap-versions.json Removes maui key; keeps only spec/google/apple in docs copy.
openiap-versions.json Removes maui key; keeps only spec/google/apple in root manifest.
libraries/react-native-iap/src/utils/errorMapping.ts Extends purchase error types/mapping to include new query diagnostics fields.
libraries/react-native-iap/src/utils/error.ts Extends parsed error shape to include new query diagnostics fields.
libraries/react-native-iap/src/index.ts Wraps fetchProducts errors into structured PurchaseError including diagnostics.
libraries/react-native-iap/android/src/test/java/com/margelo/nitro/iap/ProductQueryHelpersTest.kt Adds unit tests for new “All query” product collection helper behavior.
libraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/ProductQueryHelpers.kt Introduces helper to aggregate InApp+Subs queries with partial-success behavior.
libraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt Uses helper for All queries and serializes diagnostics via error.toJSON().
libraries/maui-iap/CLAUDE.md Clarifies the MAUI symlink purpose for native version manifest keys.
libraries/maui-iap/android/openiap/src/main/java/dev/hyo/openiap/maui/OpenIapMauiModule.kt Adds diagnostic fields to encoded error payloads.
knowledge/internal/06-git-deployment.md Documents that version manifest is only for spec/google/apple (no framework keys).
knowledge/internal/04-platform-packages.md Updates internal docs example for current manifest schema.
CLAUDE.md Clarifies openiap-versions.json scope (only spec/google/apple).
.github/workflows/release-maui.yml Reads/bump MAUI version from OpenIap.Maui.csproj instead of openiap-versions.json.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread openiap-versions.json
@hyochan
Copy link
Copy Markdown
Member Author

hyochan commented May 7, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves Android error diagnostics by including Google Play Billing response codes, debug messages, and product details in QueryProduct failures. It updates the OpenIapError hierarchy to support these diagnostics and propagates them through the Android and React Native layers. I have flagged a potential breaking change regarding the modification of the QueryProduct error type, which may require a major version bump instead of the current patch release.

Comment thread packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt Outdated
@hyochan
Copy link
Copy Markdown
Member Author

hyochan commented May 7, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances the PurchaseError model across all platforms by adding diagnostic fields for Android QueryProduct failures, including responseCode, productIds, productType, and isEmptyProductList. It updates the GraphQL schema, generated types, and documentation accordingly. Feedback identifies a compilation error caused by a typo in OpenIapError, a breaking change in Kotlin error type checking for QueryProduct, and a missing constant reference. Additionally, a type mismatch was noted between the GDScript documentation and its implementation.

Comment thread packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt Outdated
Comment thread packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt Outdated
Comment thread packages/docs/src/pages/docs/errors.tsx Outdated
@hyochan
Copy link
Copy Markdown
Member Author

hyochan commented May 7, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces detailed diagnostic fields—responseCode, productIds, productType, and isEmptyProductList—to the PurchaseError type across the entire SDK, including the GraphQL schema, documentation, and all framework libraries. The Android implementation in openiap-google is updated to populate these fields during product queries, and react-native-iap now utilizes a new concurrent fetching helper. Feedback was provided regarding a thread-safety vulnerability in the OpenIapError.QueryProduct singleton, where storing diagnostic state in a volatile property could result in race conditions during concurrent queries.

Comment thread packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt Outdated
@hyochan
Copy link
Copy Markdown
Member Author

hyochan commented May 7, 2026

/gemini review

@hyochan
Copy link
Copy Markdown
Member Author

hyochan commented May 7, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances the PurchaseError model by adding diagnostic fields—responseCode, productIds, productType, and isEmptyProductList—across all platform libraries and the GraphQL schema to improve Android error reporting. The React Native Android implementation was refactored to fetch InApp and Subs products concurrently, and error handling was unified under the OpenIapError naming convention. Documentation and release notes were updated accordingly. Feedback identified a potential race condition in the Android native QueryProduct error object due to its stateful singleton design, recommending a transition to a class-based implementation for better thread safety.

I am having trouble creating individual review comments. Click here to see my feedback.

packages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapError.kt (163-222)

high

Using a stateful singleton for QueryProduct introduces a potential race condition. If two product queries fail on different threads concurrently, one thread's call to withDiagnostics could overwrite the diagnostic data of another before it's fully processed.

While the current usage with BillingClient callbacks on the main thread might prevent this, it makes the design fragile and reliant on external guarantees. Any future use of this error from a multi-threaded context could lead to subtle bugs.

To ensure thread safety and a more robust design, consider changing QueryProduct from an object to a class or data class. This would be a breaking change, but it would eliminate the risks associated with a stateful singleton.

Example of a safer implementation:

data class QueryProduct(
    val responseCode: Int? = null,
    override val debugMessage: String? = null,
    val productIds: List<String> = emptyList(),
    val productType: String? = null,
    val isEmptyProductList: Boolean? = null,
) : OpenIapError() {
    override val code = ErrorCode.QueryProduct.rawValue
    override val message = "Failed to query product"

    override fun toJSON(): Map<String, Any?> {
        return super.toJSON() + mapOf(
            "responseCode" to responseCode,
            "productIds" to productIds,
            "productType" to productType,
            "isEmptyProductList" to isEmptyProductList,
        )
    }
}

This would require updating call sites to instantiate QueryProduct(...) instead of using the singleton. If a breaking change is not an option for this patch release, I'd recommend adding a prominent warning in the KDoc for withDiagnostics about the thread-safety implications.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces enhanced diagnostic reporting for Android QueryProduct failures by adding fields like responseCode, productIds, productType, and isEmptyProductList to the PurchaseError model across all supported platforms (Kotlin, Swift, C#, Dart, TypeScript). It also includes a new collectAllQueryProducts helper in the React Native IAP library to handle concurrent product queries and updates documentation and version manifests to reflect these changes. The review comments were filtered to remove non-actionable validation feedback, keeping only the request for a missing import.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 38 changed files in this pull request and generated no new comments.

@hyochan hyochan merged commit 7fd5b5b into main May 7, 2026
24 checks passed
@hyochan hyochan deleted the codex/fix-google-query-product-diagnostics branch May 7, 2026 17:23
@hyochan hyochan added 🛠 bugfix All kinds of bug fixes and removed 🐛 bug Something isn't working labels May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 android Related to android 🛠 bugfix All kinds of bug fixes 📖 documentation Improvements or additions to documentation maui maui library react-native-iap react-native-iap library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Android QueryProduct fails with OpenIapError$QueryProduct

2 participants