Skip to content

Commit 3141b75

Browse files
authored
Fix: Only call method channels on native platforms (#1196)
1 parent 9928a74 commit 3141b75

10 files changed

+102
-17
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Fixes
6+
7+
- Fix: Only call method channels on native platforms ([#1196](https://github.com/getsentry/sentry-dart/pull/1196))
8+
59
### Dependencies
610

711
- Bump Android SDK from v6.9.2 to v6.11.0 ([#1194](https://github.com/getsentry/sentry-dart/pull/1194), [#1209](https://github.com/getsentry/sentry-dart/pull/1209))

flutter/ios/Classes/SentryFlutterPluginApple.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ public class SentryFlutterPluginApple: NSObject, FlutterPlugin {
8686
let value = arguments?["value"] as? Any
8787
setContexts(key: key, value: value, result: result)
8888

89+
case "removeContexts":
90+
let arguments = call.arguments as? [String: Any?]
91+
let key = arguments?["key"] as? String
92+
removeContexts(key: key, result: result)
93+
8994
case "setUser":
9095
let arguments = call.arguments as? [String: Any?]
9196
let user = arguments?["user"] as? [String: Any?]

flutter/lib/src/sentry_flutter.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ mixin SentryFlutter {
4747
}
4848

4949
final nativeChannel = SentryNativeChannel(channel, flutterOptions);
50-
final native = SentryNative();
51-
native.setNativeChannel(nativeChannel);
50+
if (flutterOptions.platformChecker.hasNativeIntegration) {
51+
final native = SentryNative();
52+
native.nativeChannel = nativeChannel;
53+
}
5254

5355
final platformDispatcher = PlatformDispatcher.instance;
5456
final wrapper = PlatformDispatcherWrapper(platformDispatcher);
@@ -95,6 +97,7 @@ mixin SentryFlutter {
9597
// Not all platforms have a native integration.
9698
if (options.platformChecker.hasNativeIntegration) {
9799
options.transport = FileSystemTransport(channel, options);
100+
options.addScopeObserver(NativeScopeObserver(SentryNative()));
98101
}
99102

100103
var flutterEventProcessor =
@@ -104,7 +107,6 @@ mixin SentryFlutter {
104107
if (options.platformChecker.platform.isAndroid) {
105108
options
106109
.addEventProcessor(AndroidPlatformExceptionEventProcessor(options));
107-
options.addScopeObserver(NativeScopeObserver(SentryNative()));
108110
}
109111

110112
_setSdk(options);

flutter/lib/src/sentry_native.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ class SentryNative {
1919
return _instance;
2020
}
2121

22+
SentryNativeChannel? get nativeChannel => _instance._nativeChannel;
23+
2224
/// Provide [nativeChannel] for native communication.
23-
void setNativeChannel(SentryNativeChannel nativeChannel) {
25+
set nativeChannel(SentryNativeChannel? nativeChannel) {
2426
_instance._nativeChannel = nativeChannel;
2527
}
2628

flutter/test/integrations/native_app_start_integration_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class Fixture {
104104
late final native = SentryNative();
105105

106106
Fixture() {
107-
native.setNativeChannel(wrapper);
107+
native.nativeChannel = wrapper;
108108
native.reset();
109109
when(hub.options).thenReturn(options);
110110
}

flutter/test/mocks.mocks.dart

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,14 @@ class MockSentryTracer extends _i1.Mock implements _i8.SentryTracer {
391391
),
392392
returnValueForMissingStub: null,
393393
);
394+
@override
395+
void scheduleFinish() => super.noSuchMethod(
396+
Invocation.method(
397+
#scheduleFinish,
398+
[],
399+
),
400+
returnValueForMissingStub: null,
401+
);
394402
}
395403

396404
/// A class which mocks [MethodChannel].
@@ -496,20 +504,20 @@ class MockSentryNative extends _i1.Mock implements _i10.SentryNative {
496504
returnValueForMissingStub: null,
497505
);
498506
@override
499-
bool get didFetchAppStart => (super.noSuchMethod(
500-
Invocation.getter(#didFetchAppStart),
501-
returnValue: false,
502-
) as bool);
503-
@override
504-
void setNativeChannel(_i11.SentryNativeChannel? nativeChannel) =>
507+
set nativeChannel(_i11.SentryNativeChannel? nativeChannel) =>
505508
super.noSuchMethod(
506-
Invocation.method(
507-
#setNativeChannel,
508-
[nativeChannel],
509+
Invocation.setter(
510+
#nativeChannel,
511+
nativeChannel,
509512
),
510513
returnValueForMissingStub: null,
511514
);
512515
@override
516+
bool get didFetchAppStart => (super.noSuchMethod(
517+
Invocation.getter(#didFetchAppStart),
518+
returnValue: false,
519+
) as bool);
520+
@override
513521
_i6.Future<_i11.NativeAppStart?> fetchNativeAppStart() => (super.noSuchMethod(
514522
Invocation.method(
515523
#fetchNativeAppStart,

flutter/test/sentry_flutter_test.dart

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:sentry_flutter/sentry_flutter.dart';
66
import 'package:sentry_flutter/src/integrations/integrations.dart';
77
import 'package:sentry_flutter/src/integrations/screenshot_integration.dart';
88
import 'package:sentry_flutter/src/renderer/renderer.dart';
9+
import 'package:sentry_flutter/src/sentry_native.dart';
910
import 'package:sentry_flutter/src/version.dart';
1011
import 'mocks.dart';
1112
import 'mocks.mocks.dart';
@@ -46,17 +47,23 @@ void main() {
4647
group('Test platform integrations', () {
4748
setUp(() async {
4849
await Sentry.close();
50+
final sentryNative = SentryNative();
51+
sentryNative.nativeChannel = null;
52+
sentryNative.reset();
4953
});
5054

5155
test('Android', () async {
5256
List<Integration> integrations = [];
5357
Transport transport = MockTransport();
5458

59+
SentryFlutterOptions? sentryFlutterOptions;
60+
5561
await SentryFlutter.init(
5662
(options) async {
5763
options.dsn = fakeDsn;
5864
integrations = options.integrations;
5965
transport = options.transport;
66+
sentryFlutterOptions = options;
6067
},
6168
appRunner: appRunner,
6269
packageLoader: loadTestPackage,
@@ -68,6 +75,9 @@ void main() {
6875
hasFileSystemTransport: true,
6976
);
7077

78+
testScopeObserver(
79+
options: sentryFlutterOptions!, expectedHasNativeScopeObserver: true);
80+
7181
testConfiguration(
7282
integrations: integrations,
7383
shouldHaveIntegrations: [
@@ -86,18 +96,22 @@ void main() {
8696
beforeIntegration: WidgetsFlutterBindingIntegration,
8797
afterIntegration: OnErrorIntegration);
8898

99+
expect(SentryNative().nativeChannel, isNotNull);
100+
89101
await Sentry.close();
90102
}, testOn: 'vm');
91103

92104
test('iOS', () async {
93105
List<Integration> integrations = [];
94106
Transport transport = MockTransport();
107+
SentryFlutterOptions? sentryFlutterOptions;
95108

96109
await SentryFlutter.init(
97110
(options) async {
98111
options.dsn = fakeDsn;
99112
integrations = options.integrations;
100113
transport = options.transport;
114+
sentryFlutterOptions = options;
101115
},
102116
appRunner: appRunner,
103117
packageLoader: loadTestPackage,
@@ -109,6 +123,9 @@ void main() {
109123
hasFileSystemTransport: true,
110124
);
111125

126+
testScopeObserver(
127+
options: sentryFlutterOptions!, expectedHasNativeScopeObserver: true);
128+
112129
testConfiguration(
113130
integrations: integrations,
114131
shouldHaveIntegrations: [
@@ -125,18 +142,22 @@ void main() {
125142
beforeIntegration: WidgetsFlutterBindingIntegration,
126143
afterIntegration: OnErrorIntegration);
127144

145+
expect(SentryNative().nativeChannel, isNotNull);
146+
128147
await Sentry.close();
129148
}, testOn: 'vm');
130149

131150
test('macOS', () async {
132151
List<Integration> integrations = [];
133152
Transport transport = MockTransport();
153+
SentryFlutterOptions? sentryFlutterOptions;
134154

135155
await SentryFlutter.init(
136156
(options) async {
137157
options.dsn = fakeDsn;
138158
integrations = options.integrations;
139159
transport = options.transport;
160+
sentryFlutterOptions = options;
140161
},
141162
appRunner: appRunner,
142163
packageLoader: loadTestPackage,
@@ -148,6 +169,9 @@ void main() {
148169
hasFileSystemTransport: true,
149170
);
150171

172+
testScopeObserver(
173+
options: sentryFlutterOptions!, expectedHasNativeScopeObserver: true);
174+
151175
testConfiguration(
152176
integrations: integrations,
153177
shouldHaveIntegrations: [
@@ -164,18 +188,22 @@ void main() {
164188
beforeIntegration: WidgetsFlutterBindingIntegration,
165189
afterIntegration: OnErrorIntegration);
166190

191+
expect(SentryNative().nativeChannel, isNotNull);
192+
167193
await Sentry.close();
168194
}, testOn: 'vm');
169195

170196
test('Windows', () async {
171197
List<Integration> integrations = [];
172198
Transport transport = MockTransport();
199+
SentryFlutterOptions? sentryFlutterOptions;
173200

174201
await SentryFlutter.init(
175202
(options) async {
176203
options.dsn = fakeDsn;
177204
integrations = options.integrations;
178205
transport = options.transport;
206+
sentryFlutterOptions = options;
179207
},
180208
appRunner: appRunner,
181209
packageLoader: loadTestPackage,
@@ -187,6 +215,10 @@ void main() {
187215
hasFileSystemTransport: false,
188216
);
189217

218+
testScopeObserver(
219+
options: sentryFlutterOptions!,
220+
expectedHasNativeScopeObserver: false);
221+
190222
testConfiguration(
191223
integrations: integrations,
192224
shouldHaveIntegrations: [
@@ -205,18 +237,22 @@ void main() {
205237
beforeIntegration: WidgetsFlutterBindingIntegration,
206238
afterIntegration: OnErrorIntegration);
207239

240+
expect(SentryNative().nativeChannel, isNull);
241+
208242
await Sentry.close();
209243
}, testOn: 'vm');
210244

211245
test('Linux', () async {
212246
List<Integration> integrations = [];
213247
Transport transport = MockTransport();
248+
SentryFlutterOptions? sentryFlutterOptions;
214249

215250
await SentryFlutter.init(
216251
(options) async {
217252
options.dsn = fakeDsn;
218253
integrations = options.integrations;
219254
transport = options.transport;
255+
sentryFlutterOptions = options;
220256
},
221257
appRunner: appRunner,
222258
packageLoader: loadTestPackage,
@@ -228,6 +264,10 @@ void main() {
228264
hasFileSystemTransport: false,
229265
);
230266

267+
testScopeObserver(
268+
options: sentryFlutterOptions!,
269+
expectedHasNativeScopeObserver: false);
270+
231271
testConfiguration(
232272
integrations: integrations,
233273
shouldHaveIntegrations: [
@@ -246,18 +286,22 @@ void main() {
246286
beforeIntegration: WidgetsFlutterBindingIntegration,
247287
afterIntegration: OnErrorIntegration);
248288

289+
expect(SentryNative().nativeChannel, isNull);
290+
249291
await Sentry.close();
250292
}, testOn: 'vm');
251293

252294
test('Web', () async {
253295
List<Integration> integrations = [];
254296
Transport transport = MockTransport();
297+
SentryFlutterOptions? sentryFlutterOptions;
255298

256299
await SentryFlutter.init(
257300
(options) async {
258301
options.dsn = fakeDsn;
259302
integrations = options.integrations;
260303
transport = options.transport;
304+
sentryFlutterOptions = options;
261305
},
262306
appRunner: appRunner,
263307
packageLoader: loadTestPackage,
@@ -272,6 +316,10 @@ void main() {
272316
hasFileSystemTransport: false,
273317
);
274318

319+
testScopeObserver(
320+
options: sentryFlutterOptions!,
321+
expectedHasNativeScopeObserver: false);
322+
275323
testConfiguration(
276324
integrations: integrations,
277325
shouldHaveIntegrations: platformAgnosticIntegrations,
@@ -288,6 +336,8 @@ void main() {
288336
beforeIntegration: RunZonedGuardedIntegration,
289337
afterIntegration: WidgetsFlutterBindingIntegration);
290338

339+
expect(SentryNative().nativeChannel, isNull);
340+
291341
await Sentry.close();
292342
});
293343

flutter/test/sentry_flutter_util.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter_test/flutter_test.dart';
22
import 'package:sentry_flutter/sentry_flutter.dart';
33
import 'package:sentry_flutter/src/file_system_transport.dart';
4+
import 'package:sentry_flutter/src/native_scope_observer.dart';
45

56
void testTransport({
67
required Transport transport,
@@ -13,6 +14,19 @@ void testTransport({
1314
);
1415
}
1516

17+
void testScopeObserver(
18+
{required SentryFlutterOptions options,
19+
required bool expectedHasNativeScopeObserver}) {
20+
var actualHasNativeScopeObserver = false;
21+
for (final scopeObserver in options.scopeObservers) {
22+
if (scopeObserver.runtimeType == NativeScopeObserver) {
23+
actualHasNativeScopeObserver = true;
24+
break;
25+
}
26+
}
27+
expect(actualHasNativeScopeObserver, expectedHasNativeScopeObserver);
28+
}
29+
1630
void testConfiguration({
1731
required Iterable<Integration> integrations,
1832
required Iterable<Type> shouldHaveIntegrations,

flutter/test/sentry_native_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class Fixture {
136136

137137
SentryNative getSut() {
138138
final sut = SentryNative();
139-
sut.setNativeChannel(channel);
139+
sut.nativeChannel = channel;
140140
return sut;
141141
}
142142
}

flutter/test/sentry_navigator_observer_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void main() {
4848
final mockHub = _MockHub();
4949
final native = SentryNative();
5050
final mockNativeChannel = MockNativeChannel();
51-
native.setNativeChannel(mockNativeChannel);
51+
native.nativeChannel = mockNativeChannel;
5252

5353
final tracer = getMockSentryTracer();
5454
_whenAnyStart(mockHub, tracer);
@@ -75,7 +75,7 @@ void main() {
7575
mockNativeChannel.nativeFrames = nativeFrames;
7676

7777
final mockNative = SentryNative();
78-
mockNative.setNativeChannel(mockNativeChannel);
78+
mockNative.nativeChannel = mockNativeChannel;
7979

8080
final sut = fixture.getSut(
8181
hub: hub,

0 commit comments

Comments
 (0)