Skip to content

Commit c5b5a6f

Browse files
authored
Merge 609026b into 6d317ea
2 parents 6d317ea + 609026b commit c5b5a6f

File tree

8 files changed

+310
-145
lines changed

8 files changed

+310
-145
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Features
6+
7+
- Use PlatformDispatcher.onError in Flutter 3.3 ([#1039](https://github.com/getsentry/sentry-dart/pull/1039))
8+
39
## 6.12.1
410

511
### Dependencies

dart/lib/src/sentry.dart

+23-16
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Sentry {
3636
static Future<void> init(
3737
OptionsConfiguration optionsConfiguration, {
3838
AppRunner? appRunner,
39+
@internal bool callAppRunnerInRunZonedGuarded = true,
3940
@internal SentryOptions? options,
4041
}) async {
4142
final sentryOptions = options ?? SentryOptions();
@@ -56,7 +57,7 @@ class Sentry {
5657
throw ArgumentError('DSN is required.');
5758
}
5859

59-
await _init(sentryOptions, appRunner);
60+
await _init(sentryOptions, appRunner, callAppRunnerInRunZonedGuarded);
6061
}
6162

6263
static Future<void> _initDefaultValues(
@@ -96,7 +97,8 @@ class Sentry {
9697
}
9798

9899
/// Initializes the SDK
99-
static Future<void> _init(SentryOptions options, AppRunner? appRunner) async {
100+
static Future<void> _init(SentryOptions options, AppRunner? appRunner,
101+
bool callAppRunnerInRunZonedGuarded) async {
100102
if (isEnabled) {
101103
options.logger(
102104
SentryLevel.warning,
@@ -113,21 +115,26 @@ class Sentry {
113115

114116
// execute integrations after hub being enabled
115117
if (appRunner != null) {
116-
var runIntegrationsAndAppRunner = () async {
117-
final integrations =
118-
options.integrations.where((i) => i is! RunZonedGuardedIntegration);
119-
await _callIntegrations(integrations, options);
118+
if (callAppRunnerInRunZonedGuarded) {
119+
var runIntegrationsAndAppRunner = () async {
120+
final integrations = options.integrations
121+
.where((i) => i is! RunZonedGuardedIntegration);
122+
await _callIntegrations(integrations, options);
123+
await appRunner();
124+
};
125+
126+
final runZonedGuardedIntegration =
127+
RunZonedGuardedIntegration(runIntegrationsAndAppRunner);
128+
options.addIntegrationByIndex(0, runZonedGuardedIntegration);
129+
130+
// RunZonedGuardedIntegration will run other integrations and appRunner
131+
// runZonedGuarded so all exception caught in the error handler are
132+
// handled
133+
await runZonedGuardedIntegration(HubAdapter(), options);
134+
} else {
135+
await _callIntegrations(options.integrations, options);
120136
await appRunner();
121-
};
122-
123-
final runZonedGuardedIntegration =
124-
RunZonedGuardedIntegration(runIntegrationsAndAppRunner);
125-
options.addIntegrationByIndex(0, runZonedGuardedIntegration);
126-
127-
// RunZonedGuardedIntegration will run other integrations and appRunner
128-
// runZonedGuarded so all exception caught in the error handler are
129-
// handled
130-
await runZonedGuardedIntegration(HubAdapter(), options);
137+
}
131138
} else {
132139
await _callIntegrations(options.integrations, options);
133140
}

dart/test/sentry_test.dart

+25
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,31 @@ void main() {
284284
});
285285
});
286286

287+
test('should complete when appRunner is not called in runZonedGuarded',
288+
() async {
289+
final completer = Completer();
290+
var completed = false;
291+
292+
final init = Sentry.init(
293+
(options) {
294+
options.dsn = fakeDsn;
295+
},
296+
appRunner: () => completer.future,
297+
callAppRunnerInRunZonedGuarded: false,
298+
).whenComplete(() => completed = true);
299+
300+
await Future(() {
301+
// We make the expectation only after all microtasks have completed,
302+
// that Sentry.init might have scheduled.
303+
expect(completed, false);
304+
});
305+
306+
completer.complete();
307+
await init;
308+
309+
expect(completed, true);
310+
});
311+
287312
test('options.environment debug', () async {
288313
final sentryOptions = SentryOptions(dsn: fakeDsn)
289314
..platformChecker = FakePlatformChecker.debugMode();

flutter/lib/src/integrations/on_error_integration.dart

-4
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ class OnErrorIntegration implements Integration<SentryFlutterOptions> {
3838
// WidgetsBinding works with WidgetsFlutterBinding and other custom bindings
3939
final wrapper = dispatchWrapper ??
4040
PlatformDispatcherWrapper(binding.platformDispatcher);
41-
42-
if (!wrapper.isOnErrorSupported(options)) {
43-
return;
44-
}
4541
_defaultOnError = wrapper.onError;
4642

4743
_integrationOnError = (Object exception, StackTrace stackTrace) {

flutter/lib/src/sentry_flutter.dart

+21-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import 'dart:async';
2+
import 'dart:ui';
23

34
import 'package:flutter/scheduler.dart';
45
import 'package:flutter/services.dart';
56
import 'package:meta/meta.dart';
67
import 'package:package_info_plus/package_info_plus.dart';
7-
import 'package:sentry/sentry.dart';
8+
import '../sentry_flutter.dart';
89
import 'event_processor/android_platform_exception_event_processor.dart';
910
import 'native_scope_observer.dart';
1011
import 'sentry_native.dart';
@@ -13,9 +14,7 @@ import 'sentry_native_channel.dart';
1314
import 'event_processor/flutter_enricher_event_processor.dart';
1415
import 'integrations/debug_print_integration.dart';
1516
import 'integrations/native_app_start_integration.dart';
16-
import 'sentry_flutter_options.dart';
1717

18-
import 'default_integrations.dart';
1918
import 'file_system_transport.dart';
2019

2120
import 'version.dart';
@@ -45,27 +44,28 @@ mixin SentryFlutter {
4544
final native = SentryNative();
4645
native.setNativeChannel(nativeChannel);
4746

47+
final platformDispatcher = PlatformDispatcher.instance;
48+
final wrapper = PlatformDispatcherWrapper(platformDispatcher);
49+
final isOnErrorSupported = wrapper.isOnErrorSupported(flutterOptions);
50+
4851
// first step is to install the native integration and set default values,
4952
// so we are able to capture future errors.
5053
final defaultIntegrations = _createDefaultIntegrations(
51-
packageLoader,
52-
channel,
53-
flutterOptions,
54-
);
54+
packageLoader, channel, flutterOptions, isOnErrorSupported);
5555
for (final defaultIntegration in defaultIntegrations) {
5656
flutterOptions.addIntegration(defaultIntegration);
5757
}
5858

5959
await _initDefaultValues(flutterOptions, channel);
6060

61-
await Sentry.init(
62-
(options) async {
63-
await optionsConfiguration(options as SentryFlutterOptions);
64-
},
65-
appRunner: appRunner,
66-
// ignore: invalid_use_of_internal_member
67-
options: flutterOptions,
68-
);
61+
await Sentry.init((options) async {
62+
await optionsConfiguration(options as SentryFlutterOptions);
63+
},
64+
appRunner: appRunner,
65+
// ignore: invalid_use_of_internal_member
66+
options: flutterOptions,
67+
// ignore: invalid_use_of_internal_member
68+
callAppRunnerInRunZonedGuarded: !isOnErrorSupported);
6969
}
7070

7171
static Future<void> _initDefaultValues(
@@ -96,11 +96,17 @@ mixin SentryFlutter {
9696
PackageLoader packageLoader,
9797
MethodChannel channel,
9898
SentryFlutterOptions options,
99+
bool isOnErrorSupported,
99100
) {
100101
final integrations = <Integration>[];
101102
final platformChecker = options.platformChecker;
102103
final platform = platformChecker.platform;
103104

105+
// Use PlatformDispatcher.onError instead of zones.
106+
if (isOnErrorSupported) {
107+
integrations.add(OnErrorIntegration());
108+
}
109+
104110
// Will call WidgetsFlutterBinding.ensureInitialized() before all other integrations.
105111
integrations.add(WidgetsFlutterBindingIntegration());
106112

flutter/test/mocks.mocks.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Mocks generated by Mockito 5.3.1 from annotations
1+
// Mocks generated by Mockito 5.3.2 from annotations
22
// in sentry_flutter/example/windows/flutter/ephemeral/.plugin_symlinks/sentry_flutter/example/linux/flutter/ephemeral/.plugin_symlinks/sentry_flutter/example/ios/.symlinks/plugins/sentry_flutter/test/mocks.dart.
33
// Do not manually edit this file.
44

0 commit comments

Comments
 (0)