Skip to content

Fix Wasm incompatibility in web error processing#1684

Merged
tonidero merged 1 commit into
RevenueCat:external/brunovsiqueira/fix/wasm-js-interop-runtime-check-1651from
brunovsiqueira:fix/wasm-js-interop-runtime-check-1651
Apr 15, 2026
Merged

Fix Wasm incompatibility in web error processing#1684
tonidero merged 1 commit into
RevenueCat:external/brunovsiqueira/fix/wasm-js-interop-runtime-check-1651from
brunovsiqueira:fix/wasm-js-interop-runtime-check-1651

Conversation

@brunovsiqueira

@brunovsiqueira brunovsiqueira commented Mar 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.

@brunovsiqueira brunovsiqueira requested a review from a team as a code owner March 15, 2026 17:01
Replace `is JSObject` runtime check with Wasm-safe `isA<JSObject>()`
in `_processError`. The `is` operator on JS interop types is unreliable
under Wasm compilation due to type erasure differences between JS and
Wasm targets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@brunovsiqueira brunovsiqueira force-pushed the fix/wasm-js-interop-runtime-check-1651 branch from d78f0e4 to 0f5743b Compare March 15, 2026 17:07
@tonidero

Copy link
Copy Markdown
Contributor

Hi @brunovsiqueira, sorry for the delay and many thanks for your contribution! This looks good so we will get this merged. Should be part of the next SDK release. Thanks again!

@tonidero tonidero changed the base branch from main to external/brunovsiqueira/fix/wasm-js-interop-runtime-check-1651 April 15, 2026 11:14
@tonidero tonidero requested a review from a team as a code owner April 15, 2026 11:14
@tonidero tonidero merged commit 18b7d7f into RevenueCat:external/brunovsiqueira/fix/wasm-js-interop-runtime-check-1651 Apr 15, 2026
@brunovsiqueira

Copy link
Copy Markdown
Contributor Author

Hi @tonidero!
Happy to hear this will get released :)

Happy to contribute!

tonidero added a commit that referenced this pull request Apr 15, 2026
…ontributed by @brunovsiqueira (#1722)

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.

Contributed by @brunovsiqueira in #1684 

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: a small, localized change to web error parsing that should
only affect how JS/Dart exceptions are detected under dart2wasm and how
fallback `PlatformException`s are produced.
> 
> **Overview**
> Fixes web error processing to be **Wasm-compatible** by avoiding
`error is JSObject` checks in `_processError`.
> 
> Errors are now *safely* cast to `JSAny?` (catching `TypeError` under
dart2wasm) and validated via `isA<JSObject>()` before extracting
`code`/`message` details; non-JS errors fall back to the generic unknown
`PlatformException` path.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
826459c. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Bruno Viana de Siqueira <brunovsiq@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wasm Incompatability

2 participants