Skip to content

[EXTERNAL] Fix Wasm incompatibility in web error processing (#1684) contributed by @brunovsiqueira#1722

Merged
tonidero merged 4 commits into
mainfrom
external/brunovsiqueira/fix/wasm-js-interop-runtime-check-1651
Apr 15, 2026
Merged

[EXTERNAL] Fix Wasm incompatibility in web error processing (#1684) contributed by @brunovsiqueira#1722
tonidero merged 4 commits into
mainfrom
external/brunovsiqueira/fix/wasm-js-interop-runtime-check-1651

Conversation

@tonidero

@tonidero tonidero commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #1651

Description

The _processError method in purchases_flutter_web.dart uses error is JSObject, which triggers the
invalid_runtime_check_with_js_interop_types lint. The is operator on JS interop types is unreliable under Wasm compilation because JS interop types are erased differently between JS and Wasm targets.

This replaces the runtime check with the Wasm-safe isA<JSObject>() method from dart:js_interop (available since Dart 3.4, and the project requires Dart >=3.6.0).

  • A description about what and why you are contributing, even if it's trivial.
  • The issue number(s) or PR number(s) in the description if you are contributing in response to those.
  • If applicable, unit tests.

Changes

lib/web/purchases_flutter_web.dart

  • Cast error to JSAny? before checking
  • Replace error is JSObject with jsAny.isA<JSObject>()
  • Extract jsObject via jsAny as JSObject after the isA confirmation
  • No new imports needed (dart:js_interop is already imported)
  • Identical runtime behavior to the original code

CHANGELOG.md

  • Added bugfix entry under 9.14.0

Test plan

  • dart format . — clean
  • flutter analyze lib — passes with no issues (the invalid_runtime_check_with_js_interop_types warning is gone)
  • flutter test — all 134 tests pass
  • cd revenuecat_examples/purchase_tester && flutter build web — web build verification
  • cd revenuecat_examples/purchase_tester && flutter build web --wasm — Wasm build verification
  • CI: bundle exec fastlane run_api_tests — no public API changes (requires CI environment)

Why no new unit tests

_processError is a private method that uses dart:js_interop types requiring a web runtime. The repo has no web-platform test infrastructure (flutter test --platform chrome), and the change is a mechanical replacement of one pattern with its Wasm-safe equivalent. flutter analyze statically catches the lint if it regresses. Adding web test infra would be out of scope for this bugfix.

Contributed by @brunovsiqueira in #1684


Note

Low Risk
Low risk: localized change to web error handling that only affects how JS interop errors are detected/converted, with a safe fallback to the existing unknown-error path.

Overview
Fixes web/Wasm incompatibility in _processError by avoiding is JSObject checks and instead attempting a JSAny cast and using isA<JSObject>() for JS interop type detection.

If the error isn’t a JS interop value (e.g., under dart2wasm), the code now catches the cast TypeError, logs a warning via debugPrint, and falls back to returning an unknown PlatformException.

Reviewed by Cursor Bugbot for commit 3b05d3a. Bugbot is set up for automated code reviews on this repo. Configure here.

brunovsiqueira and others added 2 commits April 15, 2026 13:14
Fixes #1651

## Description

The `_processError` method in `purchases_flutter_web.dart` uses `error
is JSObject`, which triggers the
`invalid_runtime_check_with_js_interop_types` lint. The `is` operator on
JS interop types is unreliable under Wasm compilation because JS interop
types are erased differently between JS and Wasm targets.

This replaces the runtime check with the Wasm-safe `isA<JSObject>()`
method from `dart:js_interop` (available since Dart 3.4, and the project
requires Dart >=3.6.0).

- [x] A description about what and why you are contributing, even if
it's trivial.
- [x] The issue number(s) or PR number(s) in the description if you are
contributing in response to those.
- [x] If applicable, unit tests.

## Changes

**`lib/web/purchases_flutter_web.dart`**
- Cast `error` to `JSAny?` before checking
- Replace `error is JSObject` with `jsAny.isA<JSObject>()`
- Extract `jsObject` via `jsAny as JSObject` after the `isA`
confirmation
- No new imports needed (`dart:js_interop` is already imported)
- Identical runtime behavior to the original code

**`CHANGELOG.md`**
- Added bugfix entry under 9.14.0

## Test plan

- [x] `dart format .` — clean
- [x] `flutter analyze lib` — passes with no issues (the
`invalid_runtime_check_with_js_interop_types` warning is gone)
- [x] `flutter test` — all 134 tests pass
- [x] `cd revenuecat_examples/purchase_tester && flutter build web` —
web build verification
- [x] `cd revenuecat_examples/purchase_tester && flutter build web
--wasm` — Wasm build verification
- [ ] CI: `bundle exec fastlane run_api_tests` — no public API changes
(requires CI environment)

## Why no new unit tests

`_processError` is a private method that uses `dart:js_interop` types
requiring a web runtime. The repo has no web-platform test
infrastructure (`flutter test --platform chrome`), and the change is a
mechanical replacement of one pattern with its Wasm-safe equivalent.
`flutter analyze` statically catches the lint if it regresses. Adding
web test infra would be out of scope for this bugfix.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
@tonidero tonidero added the pr:fix A bug fix label Apr 15, 2026
@tonidero

Copy link
Copy Markdown
Contributor Author

Note that to actually get this warning in CI, we need to update flutter_lints to version 6.0.0+. I didn't do it in this PR, but I think we need to do this soonish. One thing however, is that it has min dart version of 3.8+ and we support 3.4+, so we would need to test this separately.

@tonidero tonidero marked this pull request as ready for review April 15, 2026 11:36
@tonidero tonidero requested a review from a team as a code owner April 15, 2026 11:36

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 665c3f9. Configure here.

Comment thread lib/web/purchases_flutter_web.dart Outdated

@rickvdl rickvdl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good to me, thanks! I am curious about the bugbot comment here though.

@tonidero

Copy link
Copy Markdown
Contributor Author

Indeed it was a possible issue. Fixed in 826459c

@tonidero tonidero enabled auto-merge (squash) April 15, 2026 12:52
@tonidero tonidero merged commit 9326926 into main Apr 15, 2026
17 checks passed
@tonidero tonidero deleted the external/brunovsiqueira/fix/wasm-js-interop-runtime-check-1651 branch April 15, 2026 13:00
RCGitBot added a commit that referenced this pull request Apr 17, 2026
**This is an automatic release.**

## RevenueCat SDK
### 🐞 Bugfixes
* [EXTERNAL] Fix Wasm incompatibility in web error processing (#1684)
contributed by @brunovsiqueira (#1722) via Toni Rico (@tonidero)
### 📦 Dependency Updates
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 18.1.0 (#1726) via
RevenueCat Git Bot (@RCGitBot)
* [Android
10.2.0](https://github.com/RevenueCat/purchases-android/releases/tag/10.2.0)
* [iOS
5.68.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.68.0)

### 🔄 Other Changes
* Add retry mechanism to Maestro e2e tests (#1723) via Antonio Pallares
(@ajpallares)
* Bump fastlane-plugin-revenuecat_internal from `20911d1` to `a1eed48`
(#1725) via dependabot[bot] (@dependabot[bot])
* Skip test cases list in maestro tests using launch arguments (#1714)
via Antonio Pallares (@ajpallares)
* Add CircleCI job for maestro E2E tests (#1699) via Antonio Pallares
(@ajpallares)
* Add maestro E2E test for purchase through paywall (#1698) via Antonio
Pallares (@ajpallares)
* Add maestro E2E test app (#1654) via Antonio Pallares (@ajpallares)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk release bookkeeping: primarily version bumps and
changelog/version-matrix updates, with no functional logic changes in
the plugin code beyond reporting the new version string.
> 
> **Overview**
> Updates the SDKs to **v`10.0.1`** by bumping version identifiers
across `pubspec.yaml`, Android Gradle configs, and iOS/macOS podspecs
(including the runtime-reported plugin version strings).
> 
> Refreshes release documentation (`CHANGELOG.md`,
`CHANGELOG-LATEST.md`, `VERSIONS.md`) to include the `10.0.1` notes
(Wasm web error-processing fix) and the dependency bump to
`purchases-hybrid-common` `18.1.0` (Android `10.2.0`, iOS `5.68.0`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ff0bb5e. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wasm Incompatability

3 participants