diff --git a/CHANGELOG.md b/CHANGELOG.md index d5fac9c752..cadf415d7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Features - Use `recordHttpBreadcrumbs` to set iOS `enableNetworkBreadcrumbs` ([#1884](https://github.com/getsentry/sentry-dart/pull/1884)) +- Apply `beforeBreadcrumb` on native iOS crumbs ([#1914](https://github.com/getsentry/sentry-dart/pull/1914)) - Add `maxQueueSize` to limit the number of unawaited events sent to Sentry ([#1868](https://github.com/getsentry/sentry-dart/pull/1868)) ### Improvements diff --git a/flutter/lib/src/integrations/load_contexts_integration.dart b/flutter/lib/src/integrations/load_contexts_integration.dart index 710d7d0924..c77981d35c 100644 --- a/flutter/lib/src/integrations/load_contexts_integration.dart +++ b/flutter/lib/src/integrations/load_contexts_integration.dart @@ -155,13 +155,23 @@ class _LoadContextsIntegrationEventProcessor implements EventProcessor { final breadcrumbsJson = List>.from(breadcrumbsList); final breadcrumbs = []; + final beforeBreadcrumb = _options.beforeBreadcrumb; for (final breadcrumbJson in breadcrumbsJson) { final breadcrumb = Breadcrumb.fromJson( Map.from(breadcrumbJson), ); - breadcrumbs.add(breadcrumb); + + if (beforeBreadcrumb != null) { + final processedBreadcrumb = beforeBreadcrumb(breadcrumb); + if (processedBreadcrumb != null) { + breadcrumbs.add(processedBreadcrumb); + } + } else { + breadcrumbs.add(breadcrumb); + } } + event = event.copyWith(breadcrumbs: breadcrumbs); } diff --git a/flutter/test/integrations/load_contexts_integration_test.dart b/flutter/test/integrations/load_contexts_integration_test.dart index a97b35db77..29aed18027 100644 --- a/flutter/test/integrations/load_contexts_integration_test.dart +++ b/flutter/test/integrations/load_contexts_integration_test.dart @@ -88,6 +88,42 @@ void main() { expect(event.breadcrumbs!.length, 1); expect(event.breadcrumbs!.first.message, 'event'); }); + + test('apply beforeBreadcrumb to native breadcrumbs', () async { + fixture.options.enableScopeSync = true; + fixture.options.beforeBreadcrumb = (breadcrumb, {hint}) { + if (breadcrumb?.message == 'native-mutated') { + return breadcrumb?.copyWith(message: 'native-mutated-applied'); + } else { + return null; + } + }; + + final eventBreadcrumb = Breadcrumb(message: 'event'); + var event = SentryEvent(breadcrumbs: [eventBreadcrumb]); + + final nativeMutatedBreadcrumb = Breadcrumb(message: 'native-mutated'); + final nativeDeletedBreadcrumb = Breadcrumb(message: 'native-deleted'); + Map loadContexts = { + 'breadcrumbs': [ + nativeMutatedBreadcrumb.toJson(), + nativeDeletedBreadcrumb.toJson(), + ] + }; + + final future = Future.value(loadContexts); + when(fixture.methodChannel.invokeMethod('loadContexts')) + .thenAnswer((_) => future); + // ignore: deprecated_member_use + _channel.setMockMethodCallHandler((MethodCall methodCall) async {}); + + final integration = LoadContextsIntegration(fixture.methodChannel); + integration.call(fixture.hub, fixture.options); + event = (await fixture.options.eventProcessors.first.apply(event))!; + + expect(event.breadcrumbs!.length, 1); + expect(event.breadcrumbs!.first.message, 'native-mutated-applied'); + }); }); }