Skip to content

Commit c74a3d2

Browse files
authored
fix(android): Properly remove duplicated breadcrumbs (#5841)
* fix(android): Properly remove duplicated breadcrumbs This should fix duplicated breadcrumbs on Android. - Sentry syncs breadcrumbs from JS and native - In the past JS breadcrumbs was filtered out before sent to JS side - This filter worked on iterator of native Scope and broke when Native Android SDK replaces raw Scope with some composite scope class which plays role of "view" to sevral downstream Scope objects - This patch change filter to work on materialized breadcrumbs array just after serialization * chore: use proper generic types * chore: make linter happy as suggested * chore: make linter even happier * chore: finally fix java formatting * chore: rewrite filtering algorithm to be more resilent to crashes - use runtime type checks where possible without reducing perf - use only features of java 8 so our tests can pass
1 parent 4ff35e2 commit c74a3d2

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import com.facebook.react.bridge.WritableMap;
2929
import com.facebook.react.bridge.WritableNativeArray;
3030
import com.facebook.react.bridge.WritableNativeMap;
31-
import io.sentry.Breadcrumb;
3231
import io.sentry.ILogger;
3332
import io.sentry.IScope;
3433
import io.sentry.ISentryExecutorService;
@@ -73,7 +72,6 @@
7372
import java.nio.charset.Charset;
7473
import java.util.ArrayList;
7574
import java.util.HashMap;
76-
import java.util.Iterator;
7775
import java.util.List;
7876
import java.util.Map;
7977
import java.util.Properties;
@@ -866,19 +864,25 @@ protected void fetchNativeDeviceContexts(
866864
promise.resolve(null);
867865
return;
868866
}
869-
if (currentScope != null) {
870-
// Remove react-native breadcrumbs
871-
Iterator<Breadcrumb> breadcrumbsIterator = currentScope.getBreadcrumbs().iterator();
872-
while (breadcrumbsIterator.hasNext()) {
873-
Breadcrumb breadcrumb = breadcrumbsIterator.next();
874-
if ("react-native".equals(breadcrumb.getOrigin())) {
875-
breadcrumbsIterator.remove();
867+
868+
final @NotNull Map<String, Object> serialized =
869+
InternalSentrySdk.serializeScope(context, (SentryAndroidOptions) options, currentScope);
870+
871+
final @Nullable Object serializedBreadcrumbs = serialized.get("breadcrumbs");
872+
if (serializedBreadcrumbs instanceof List) {
873+
final List<?> breadcrumbs = (List<?>) serializedBreadcrumbs;
874+
List<Map<?, ?>> filtered = new ArrayList<>();
875+
for (Object o : breadcrumbs) {
876+
if (o instanceof Map) {
877+
final Map<?, ?> breadcrumb = (Map<?, ?>) o;
878+
if (!"react-native".equals(breadcrumb.get("origin"))) {
879+
filtered.add(breadcrumb);
880+
}
876881
}
877882
}
883+
serialized.put("breadcrumbs", filtered);
878884
}
879885

880-
final @NotNull Map<String, Object> serialized =
881-
InternalSentrySdk.serializeScope(context, (SentryAndroidOptions) options, currentScope);
882886
final @Nullable Object deviceContext = RNSentryMapConverter.convertToWritable(serialized);
883887
promise.resolve(deviceContext);
884888
}

0 commit comments

Comments
 (0)