Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter multiview support #2225

Closed
p-mazhnik opened this issue Aug 10, 2024 · 4 comments
Closed

Flutter multiview support #2225

p-mazhnik opened this issue Aug 10, 2024 · 4 comments

Comments

@p-mazhnik
Copy link

p-mazhnik commented Aug 10, 2024

Platform

Flutter Web

Obfuscation

Disabled

Debug Info

Disabled

Doctor

[✓] Flutter (Channel stable, 3.24.0, on macOS 14.4.1 23E224 darwin-arm64)
    • Flutter version 3.24.0 on channel stable
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 80c2e84975 (11 days ago), 2024-07-30 23:06:49 +0700
    • Engine revision b8800d88be
    • Dart version 3.5.0
    • DevTools version 2.37.2

Version

8.7.0


Flutter 3.24 introduced multiview support in web: https://docs.flutter.dev/platform-integration/web/embedding-flutter-web#enable-multi-view-mode.
This makes code that uses WidgetsBinding.instance.window incompatible with this Flutter version when multiview is enabled. Note that window getter was already marked as deprecated and warning is currently ignored in Sentry codebase:

// ignore: deprecated_member_use
final window = _options.bindingUtils.instance?.window;

Steps to Reproduce

  1. Use Flutter 3.24 and follow Flutter docs to enable multiview support in web
  2. Setup Sentry
  3. Run the web app

Reproduction code: https://github.com/p-mazhnik/sentry-dart/tree/multiview-issue/flutter/example (based on flutter/example package from this repo)

Expected Result

No error, app is launched successfully

Actual Result

App is not loaded, error in console

══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════
js_primitives.dart:28 The following assertion was thrown:
js_primitives.dart:28 Assertion failed: org-dartlang-sdk:///lib/_engine/engine/window.dart:693:5
js_primitives.dart:28 _window != null
js_primitives.dart:28 "Trying to access the implicit FlutterView, but it is not available.\nNote: the implicit FlutterView
js_primitives.dart:28 is not available in multi-view mode."
js_primitives.dart:28 
js_primitives.dart:28 When the exception was thrown, this was the stack:
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:3      throw_
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3       assertFailed
js_primitives.dart:28 lib/_engine/engine/window.dart 693:13                                            get window
js_primitives.dart:28 lib/ui/window.dart 171:45                                                        get window
js_primitives.dart:28 packages/flutter/src/foundation/binding.dart 222:46                              get window
js_primitives.dart:28 packages/sentry_flutter/src/widgets_binding_observer.dart 42:54                  new
js_primitives.dart:28 packages/sentry_flutter/src/integrations/widgets_binding_integration.dart 16:22  call
js_primitives.dart:28 packages/sentry/src/sentry.dart 163:34                                           _callIntegrations
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54               runBody
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 127:5               _async
js_primitives.dart:28 packages/sentry/src/sentry.dart 160:40                                           _callIntegrations
js_primitives.dart:28 packages/sentry/src/sentry.dart 139:17                                           <fn>
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54               runBody
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 127:5               _async
js_primitives.dart:28 packages/sentry/src/sentry.dart 136:43                                           <fn>
js_primitives.dart:28 packages/sentry/src/run_zoned_guarded_integration.dart 75:24                     <fn>
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54               runBody
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 127:5               _async
js_primitives.dart:28 packages/sentry/src/run_zoned_guarded_integration.dart 73:7                      <fn>
js_primitives.dart:28 dart-sdk/lib/async/zone.dart 1399:13                                             _rootRun
js_primitives.dart:28 dart-sdk/lib/async/zone.dart 1301:19                                             run
js_primitives.dart:28 dart-sdk/lib/async/zone.dart 1825:67                                             _runZoned
js_primitives.dart:28 dart-sdk/lib/async/zone.dart 1814:12                                             runZonedGuarded
js_primitives.dart:28 packages/sentry/src/run_zoned_guarded_integration.dart 72:5                      call
js_primitives.dart:28 packages/sentry/src/sentry.dart 150:41                                           _init
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50               <fn>
js_primitives.dart:28 dart-sdk/lib/async/zone.dart 1661:54                                             runUnary
js_primitives.dart:28 dart-sdk/lib/async/future_impl.dart 163:18                                       handleValue
js_primitives.dart:28 dart-sdk/lib/async/future_impl.dart 861:44                                       handleValueCallback
js_primitives.dart:28 dart-sdk/lib/async/future_impl.dart 890:13                                       _propagateToListeners
js_primitives.dart:28 dart-sdk/lib/async/future_impl.dart 666:5                                        [_completeWithValue]
js_primitives.dart:28 dart-sdk/lib/async/future_impl.dart 736:7                                        callback
js_primitives.dart:28 dart-sdk/lib/async/schedule_microtask.dart 40:11                                 _microtaskLoop
js_primitives.dart:28 dart-sdk/lib/async/schedule_microtask.dart 49:5                                  _startMicrotaskLoop
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7               <fn>
js_primitives.dart:28 ════════════════════════════════════════════════════════════════════════════════════════════════════

Are you willing to submit a PR?

None

@buenaflor
Copy link
Contributor

hey, thx for the issue, I'll have a look here

@buenaflor
Copy link
Contributor

buenaflor commented Sep 10, 2024

hey we're making a short doc on how to make sentry flutter compatible with multiview: getsentry/sentry-docs#11308

there are a couple things that currently do not work/need to be disabled by you with multiview such as user interaction integration, screenshots etc..

more info will follow

@buenaflor buenaflor moved this from In Progress to Needs Review in Mobile & Cross Platform SDK Sep 12, 2024
@buenaflor buenaflor moved this from Needs Review to Blocked in Mobile & Cross Platform SDK Oct 28, 2024
@martinhaintz
Copy link
Collaborator

@p-mazhnik The root causes are, that the implicitView is not available when multi-view is enabled but implicitView is used inside the Sentry Plugi. Furthermore, Sentry also uses GlobalKeys which should be unique, but on a multi-view application, multiple instances of the same keys are instantiated, which results in errors.
As @buenaflor already wrote, we will update the docs, and also provide a small example, about using Sentry in a multi-view application and its current limitations.

Until the docs are updated, here is a summary:

  • SentryScreenshotWidget and SentryUserInteractionWidget which are both part of the SentryWidget are not compatible, and cannot used in a multi-view app.
  • WidgetsBindingIntegration is also not compatible with multi-view. Here is an example, of how to disable/remove it:
import 'package:sentry_flutter/src/integrations/widgets_binding_integration.dart';
...
SentryFlutter.init(
  (options) {
    ...
    final integration = options.integrations
        .firstWhere((element) => element is WidgetsBindingIntegration);
    options.removeIntegration(integration);
  },
  // Init your App.
  appRunner: appRunner,
);

Just for completeness, here is a link to the Flutter docs explaining the basics and how to enable multi-view for Flutter, but I assume, that you have already found and read this page.

@buenaflor
Copy link
Contributor

Docs have been merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants