Skip to content

Commit ab0eee1

Browse files
authored
fix: context defualts on native platforms other than iOS/Android (#2439)
* fix: context defualts on native platforms other than iOS/Android * update tests * analyzer issues * chore: update changelog
1 parent 7f97e6c commit ab0eee1

File tree

6 files changed

+93
-107
lines changed

6 files changed

+93
-107
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
- Linux native error & obfuscation support ([#2431](https://github.com/getsentry/sentry-dart/pull/2431))
3535
- Improve Device context on plain Dart and Flutter desktop apps ([#2441](https://github.com/getsentry/sentry-dart/pull/2441))
3636

37+
### Fixes
38+
39+
- OS & device contexts missing on Windows ([#2439](https://github.com/getsentry/sentry-dart/pull/2439))
40+
3741
### Dependencies
3842

3943
- Bump Cocoa SDK from v8.40.1 to v8.41.0 ([#2442](https://github.com/getsentry/sentry-dart/pull/2442))

dart/lib/src/event_processor/enricher/io_enricher_event_processor.dart

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,12 @@ class IoEnricherEventProcessor implements EnricherEventProcessor {
4040
// Amend app with current memory usage, as this is not available on native.
4141
final app = _getApp(event.contexts.app);
4242

43-
// If there's a native integration available, it probably has better
44-
// information available than Flutter.
45-
46-
final device = _options.platformChecker.hasNativeIntegration
47-
? null
48-
: _getDevice(event.contexts.device);
49-
50-
final os = _options.platformChecker.hasNativeIntegration
51-
? null
52-
: _getOperatingSystem(event.contexts.operatingSystem);
53-
54-
final culture = _options.platformChecker.hasNativeIntegration
55-
? null
56-
: _getSentryCulture(event.contexts.culture);
57-
5843
final contexts = event.contexts.copyWith(
59-
device: device,
60-
operatingSystem: os,
44+
device: _getDevice(event.contexts.device),
45+
operatingSystem: _getOperatingSystem(event.contexts.operatingSystem),
6146
runtimes: _getRuntimes(event.contexts.runtimes),
6247
app: app,
63-
culture: culture,
48+
culture: _getSentryCulture(event.contexts.culture),
6449
);
6550

6651
contexts['dart_context'] = _getDartContext();

dart/test/event_processor/enricher/io_enricher_test.dart

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,18 @@ void main() {
4343
expect(event.contexts.runtimes.length, 2);
4444
});
4545

46-
test('does not add device, os and culture if native integration is available',
47-
() {
48-
final enricher = fixture.getSut(hasNativeIntegration: true);
49-
final event = enricher.apply(SentryEvent(), Hint());
50-
51-
expect(event?.contexts.device, isNull);
52-
expect(event?.contexts.operatingSystem, isNull);
53-
expect(event?.contexts.culture, isNull);
54-
});
55-
56-
test('adds device, os and culture if no native integration is available', () {
57-
final enricher = fixture.getSut(hasNativeIntegration: false);
58-
final event = enricher.apply(SentryEvent(), Hint());
59-
60-
expect(event?.contexts.device, isNotNull);
61-
expect(event?.contexts.operatingSystem, isNotNull);
62-
expect(event?.contexts.culture, isNotNull);
46+
group('adds device, os and culture', () {
47+
for (final hasNativeIntegration in [true, false]) {
48+
test('native=$hasNativeIntegration', () {
49+
final enricher =
50+
fixture.getSut(hasNativeIntegration: hasNativeIntegration);
51+
final event = enricher.apply(SentryEvent(), Hint());
52+
53+
expect(event?.contexts.device, isNotNull);
54+
expect(event?.contexts.operatingSystem, isNotNull);
55+
expect(event?.contexts.culture, isNotNull);
56+
});
57+
}
6358
});
6459

6560
test('device has name', () {

flutter/lib/src/integrations/load_contexts_integration.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import 'dart:async';
22

33
import 'package:sentry/sentry.dart';
4+
import 'package:collection/collection.dart';
5+
// ignore: implementation_imports
6+
import 'package:sentry/src/event_processor/enricher/enricher_event_processor.dart';
47
import '../native/sentry_native_binding.dart';
58
import '../sentry_flutter_options.dart';
69

@@ -24,6 +27,21 @@ class LoadContextsIntegration extends Integration<SentryFlutterOptions> {
2427
options.addEventProcessor(
2528
_LoadContextsIntegrationEventProcessor(_native, options),
2629
);
30+
31+
// We need to move [IOEnricherEventProcessor] after [_LoadContextsIntegrationEventProcessor]
32+
// so that we know which contexts were set by the user and which were set by the other processor.
33+
// The priorities are:
34+
// - user-set context values
35+
// - context values set from native (this)
36+
// - values set from IOEnricherEventProcessor
37+
final enricherEventProcessor = options.eventProcessors.firstWhereOrNull(
38+
(element) => element is EnricherEventProcessor,
39+
);
40+
if (enricherEventProcessor != null) {
41+
options.removeEventProcessor(enricherEventProcessor);
42+
options.addEventProcessor(enricherEventProcessor);
43+
}
44+
2745
options.sdk.addIntegration('loadContextsIntegration');
2846
}
2947
}

flutter/test/sentry_flutter_test.dart

Lines changed: 39 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:package_info_plus/package_info_plus.dart';
66
import 'package:sentry/src/platform/platform.dart';
77
import 'package:sentry/src/dart_exception_type_identifier.dart';
88
import 'package:sentry_flutter/sentry_flutter.dart';
9+
import 'package:sentry_flutter/src/file_system_transport.dart';
910
import 'package:sentry_flutter/src/flutter_exception_type_identifier.dart';
1011
import 'package:sentry_flutter/src/integrations/connectivity/connectivity_integration.dart';
1112
import 'package:sentry_flutter/src/integrations/integrations.dart';
@@ -70,34 +71,31 @@ void main() {
7071
});
7172

7273
test('Android', () async {
73-
List<Integration> integrations = [];
74-
Transport transport = MockTransport();
74+
late final SentryFlutterOptions options;
75+
late final Transport transport;
7576

7677
final sentryFlutterOptions = defaultTestOptions(
7778
getPlatformChecker(platform: MockPlatform.android()))
7879
..methodChannel = native.channel;
7980

8081
await SentryFlutter.init(
81-
(options) async {
82-
options.dsn = fakeDsn;
83-
options.profilesSampleRate = 1.0;
84-
integrations = options.integrations;
85-
transport = options.transport;
82+
(o) async {
83+
o.dsn = fakeDsn;
84+
o.profilesSampleRate = 1.0;
85+
options = o;
86+
transport = o.transport;
8687
},
8788
appRunner: appRunner,
8889
options: sentryFlutterOptions,
8990
);
9091

91-
testTransport(
92-
transport: transport,
93-
hasFileSystemTransport: true,
94-
);
92+
expect(transport, isA<FileSystemTransport>());
9593

9694
testScopeObserver(
9795
options: sentryFlutterOptions, expectedHasNativeScopeObserver: true);
9896

9997
testConfiguration(
100-
integrations: integrations,
98+
integrations: options.integrations,
10199
shouldHaveIntegrations: [
102100
...androidIntegrations,
103101
...nativeIntegrations,
@@ -110,49 +108,51 @@ void main() {
110108
],
111109
);
112110

113-
integrations
111+
options.integrations
114112
.indexWhere((element) => element is WidgetsFlutterBindingIntegration);
115113

116114
testBefore(
117-
integrations: integrations,
115+
integrations: options.integrations,
118116
beforeIntegration: WidgetsFlutterBindingIntegration,
119117
afterIntegration: OnErrorIntegration);
120118

119+
expect(
120+
options.eventProcessors.indexOfTypeString('IoEnricherEventProcessor'),
121+
greaterThan(options.eventProcessors
122+
.indexOfTypeString('_LoadContextsIntegrationEventProcessor')));
123+
121124
expect(SentryFlutter.native, isNotNull);
122125
expect(Sentry.currentHub.profilerFactory, isNull);
123126

124127
await Sentry.close();
125128
}, testOn: 'vm');
126129

127130
test('iOS', () async {
128-
List<Integration> integrations = [];
129-
Transport transport = MockTransport();
131+
late final SentryFlutterOptions options;
132+
late final Transport transport;
130133

131134
final sentryFlutterOptions =
132135
defaultTestOptions(getPlatformChecker(platform: MockPlatform.iOs()))
133136
..methodChannel = native.channel;
134137

135138
await SentryFlutter.init(
136-
(options) async {
137-
options.dsn = fakeDsn;
138-
options.profilesSampleRate = 1.0;
139-
integrations = options.integrations;
140-
transport = options.transport;
139+
(o) async {
140+
o.dsn = fakeDsn;
141+
o.profilesSampleRate = 1.0;
142+
options = o;
143+
transport = o.transport;
141144
},
142145
appRunner: appRunner,
143146
options: sentryFlutterOptions,
144147
);
145148

146-
testTransport(
147-
transport: transport,
148-
hasFileSystemTransport: true,
149-
);
149+
expect(transport, isA<FileSystemTransport>());
150150

151151
testScopeObserver(
152152
options: sentryFlutterOptions, expectedHasNativeScopeObserver: true);
153153

154154
testConfiguration(
155-
integrations: integrations,
155+
integrations: options.integrations,
156156
shouldHaveIntegrations: [
157157
...iOsAndMacOsIntegrations,
158158
...nativeIntegrations,
@@ -166,14 +166,19 @@ void main() {
166166
);
167167

168168
testBefore(
169-
integrations: integrations,
169+
integrations: options.integrations,
170170
beforeIntegration: WidgetsFlutterBindingIntegration,
171171
afterIntegration: OnErrorIntegration);
172172

173173
expect(SentryFlutter.native, isNotNull);
174174
expect(Sentry.currentHub.profilerFactory,
175175
isInstanceOf<SentryNativeProfilerFactory>());
176176

177+
expect(
178+
options.eventProcessors.indexOfTypeString('IoEnricherEventProcessor'),
179+
greaterThan(options.eventProcessors
180+
.indexOfTypeString('_LoadContextsIntegrationEventProcessor')));
181+
177182
await Sentry.close();
178183
}, testOn: 'vm');
179184

@@ -195,10 +200,7 @@ void main() {
195200
options: sentryFlutterOptions,
196201
);
197202

198-
testTransport(
199-
transport: transport,
200-
hasFileSystemTransport: true,
201-
);
203+
expect(transport, isA<FileSystemTransport>());
202204

203205
testScopeObserver(
204206
options: sentryFlutterOptions, expectedHasNativeScopeObserver: true);
@@ -244,10 +246,7 @@ void main() {
244246
options: sentryFlutterOptions,
245247
);
246248

247-
testTransport(
248-
transport: transport,
249-
hasFileSystemTransport: false,
250-
);
249+
expect(transport, isNot(isA<FileSystemTransport>()));
251250

252251
testScopeObserver(
253252
options: sentryFlutterOptions, expectedHasNativeScopeObserver: true);
@@ -295,10 +294,7 @@ void main() {
295294
options: sentryFlutterOptions,
296295
);
297296

298-
testTransport(
299-
transport: transport,
300-
hasFileSystemTransport: false,
301-
);
297+
expect(transport, isNot(isA<FileSystemTransport>()));
302298

303299
testScopeObserver(
304300
options: sentryFlutterOptions, expectedHasNativeScopeObserver: true);
@@ -345,10 +341,7 @@ void main() {
345341
options: sentryFlutterOptions,
346342
);
347343

348-
testTransport(
349-
transport: transport,
350-
hasFileSystemTransport: false,
351-
);
344+
expect(transport, isNot(isA<FileSystemTransport>()));
352345

353346
testScopeObserver(
354347
options: sentryFlutterOptions, expectedHasNativeScopeObserver: false);
@@ -396,10 +389,7 @@ void main() {
396389
options: sentryFlutterOptions,
397390
);
398391

399-
testTransport(
400-
transport: transport,
401-
hasFileSystemTransport: false,
402-
);
392+
expect(transport, isNot(isA<FileSystemTransport>()));
403393

404394
testConfiguration(
405395
integrations: integrations,
@@ -441,10 +431,7 @@ void main() {
441431
options: sentryFlutterOptions,
442432
);
443433

444-
testTransport(
445-
transport: transport,
446-
hasFileSystemTransport: false,
447-
);
434+
expect(transport, isNot(isA<FileSystemTransport>()));
448435

449436
testConfiguration(
450437
integrations: integrations,
@@ -487,10 +474,7 @@ void main() {
487474
options: sentryFlutterOptions,
488475
);
489476

490-
testTransport(
491-
transport: transport,
492-
hasFileSystemTransport: false,
493-
);
477+
expect(transport, isNot(isA<FileSystemTransport>()));
494478

495479
testConfiguration(
496480
integrations: integrations,

flutter/test/sentry_flutter_util.dart

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,7 @@
11
import 'package:flutter_test/flutter_test.dart';
22
import 'package:sentry_flutter/sentry_flutter.dart';
3-
import 'package:sentry_flutter/src/file_system_transport.dart';
43
import 'package:sentry_flutter/src/native/native_scope_observer.dart';
54

6-
void testTransport({
7-
required Transport transport,
8-
required bool hasFileSystemTransport,
9-
}) {
10-
expect(
11-
transport is FileSystemTransport,
12-
hasFileSystemTransport,
13-
reason: '$FileSystemTransport was wrongly set',
14-
);
15-
}
16-
175
void testScopeObserver(
186
{required SentryFlutterOptions options,
197
required bool expectedHasNativeScopeObserver}) {
@@ -54,9 +42,21 @@ void testBefore({
5442
required Type beforeIntegration,
5543
required Type afterIntegration,
5644
}) {
57-
final beforeIndex = integrations
58-
.indexWhere((element) => element.runtimeType == beforeIntegration);
59-
final afterIndex = integrations
60-
.indexWhere((element) => element.runtimeType == afterIntegration);
61-
expect(beforeIndex < afterIndex, true);
45+
expect(integrations.indexOfType(beforeIntegration),
46+
lessThan(integrations.indexOfType(afterIntegration)));
47+
}
48+
49+
extension ListExtension<T> on List<T> {
50+
int indexOfType(Type type) {
51+
final index = indexWhere((element) => element.runtimeType == type);
52+
expect(index, greaterThanOrEqualTo(0), reason: '$type not found in $this');
53+
return index;
54+
}
55+
56+
int indexOfTypeString(String type) {
57+
final index =
58+
indexWhere((element) => element.runtimeType.toString() == type);
59+
expect(index, greaterThanOrEqualTo(0), reason: '$type not found in $this');
60+
return index;
61+
}
6262
}

0 commit comments

Comments
 (0)