@sentry/react-native 6.0.0 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +5 -9
  2. package/RNSentry.podspec +1 -1
  3. package/android/build.gradle +1 -1
  4. package/android/src/main/java/io/sentry/react/RNSentryBreadcrumb.java +7 -3
  5. package/android/src/main/java/io/sentry/react/RNSentryMapConverter.java +5 -1
  6. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +151 -145
  7. package/android/src/main/java/io/sentry/react/RNSentryReactFragmentLifecycleTracer.java +1 -1
  8. package/android/src/main/java/io/sentry/react/RNSentryReplayBreadcrumbConverter.java +10 -14
  9. package/android/src/main/java/io/sentry/react/RNSentryTimeToDisplay.java +42 -0
  10. package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +5 -0
  11. package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +5 -0
  12. package/dist/js/NativeRNSentry.d.ts +1 -0
  13. package/dist/js/NativeRNSentry.d.ts.map +1 -1
  14. package/dist/js/NativeRNSentry.js.map +1 -1
  15. package/dist/js/client.d.ts.map +1 -1
  16. package/dist/js/client.js +5 -2
  17. package/dist/js/client.js.map +1 -1
  18. package/dist/js/index.d.ts +2 -2
  19. package/dist/js/index.d.ts.map +1 -1
  20. package/dist/js/index.js +1 -1
  21. package/dist/js/index.js.map +1 -1
  22. package/dist/js/integrations/spotlight.d.ts +4 -0
  23. package/dist/js/integrations/spotlight.d.ts.map +1 -1
  24. package/dist/js/integrations/spotlight.js +4 -1
  25. package/dist/js/integrations/spotlight.js.map +1 -1
  26. package/dist/js/tracing/reactnavigation.js +7 -7
  27. package/dist/js/tracing/reactnavigation.js.map +1 -1
  28. package/dist/js/utils/ignorerequirecyclelogs.d.ts +6 -1
  29. package/dist/js/utils/ignorerequirecyclelogs.d.ts.map +1 -1
  30. package/dist/js/utils/ignorerequirecyclelogs.js +6 -2
  31. package/dist/js/utils/ignorerequirecyclelogs.js.map +1 -1
  32. package/dist/js/utils/sentryeventemitterfallback.d.ts +19 -0
  33. package/dist/js/utils/sentryeventemitterfallback.d.ts.map +1 -0
  34. package/dist/js/utils/sentryeventemitterfallback.js +78 -0
  35. package/dist/js/utils/sentryeventemitterfallback.js.map +1 -0
  36. package/dist/js/vendor/react-native/index.d.ts +1 -1
  37. package/dist/js/vendor/react-native/index.js.map +1 -1
  38. package/dist/js/version.d.ts +1 -1
  39. package/dist/js/version.js +1 -1
  40. package/dist/js/version.js.map +1 -1
  41. package/dist/js/wrapper.d.ts +3 -0
  42. package/dist/js/wrapper.d.ts.map +1 -1
  43. package/dist/js/wrapper.js +6 -0
  44. package/dist/js/wrapper.js.map +1 -1
  45. package/ios/RNSentry.h +8 -12
  46. package/ios/RNSentry.mm +382 -303
  47. package/ios/RNSentryBreadcrumb.h +2 -2
  48. package/ios/RNSentryBreadcrumb.m +7 -6
  49. package/ios/RNSentryDependencyContainer.h +2 -2
  50. package/ios/RNSentryDependencyContainer.m +7 -6
  51. package/ios/RNSentryFramesTrackerListener.h +6 -6
  52. package/ios/RNSentryFramesTrackerListener.m +10 -8
  53. package/ios/RNSentryId.m +2 -1
  54. package/ios/RNSentryOnDrawReporter.h +5 -5
  55. package/ios/RNSentryOnDrawReporter.m +26 -24
  56. package/ios/RNSentryRNSScreen.h +1 -1
  57. package/ios/RNSentryRNSScreen.m +18 -18
  58. package/ios/RNSentryReplay.m +42 -53
  59. package/ios/RNSentryReplayBreadcrumbConverter.h +3 -4
  60. package/ios/RNSentryReplayBreadcrumbConverter.m +139 -132
  61. package/ios/RNSentryTimeToDisplay.h +7 -0
  62. package/ios/RNSentryTimeToDisplay.m +44 -0
  63. package/package.json +16 -15
  64. package/plugin/build/utils.js +6 -6
  65. package/plugin/build/withSentry.js +2 -2
  66. package/plugin/build/withSentryAndroid.js +2 -2
  67. package/plugin/build/withSentryIOS.js +3 -3
  68. package/scripts/sentry-xcode-debug-files.sh +2 -0
  69. package/sentry.gradle +10 -2
  70. package/src/js/NativeRNSentry.ts +1 -0
  71. package/ts3.8/dist/js/NativeRNSentry.d.ts +1 -0
  72. package/ts3.8/dist/js/index.d.ts +2 -2
  73. package/ts3.8/dist/js/integrations/spotlight.d.ts +4 -0
  74. package/ts3.8/dist/js/utils/ignorerequirecyclelogs.d.ts +6 -1
  75. package/ts3.8/dist/js/utils/sentryeventemitterfallback.d.ts +19 -0
  76. package/ts3.8/dist/js/vendor/react-native/index.d.ts +1 -1
  77. package/ts3.8/dist/js/version.d.ts +1 -1
  78. package/ts3.8/dist/js/wrapper.d.ts +3 -0
package/README.md CHANGED
@@ -1,12 +1,8 @@
1
- <p align="center">
2
- <a href="https://sentry.io/?utm_source=github&utm_medium=logo" target="_blank">
3
- <picture>
4
- <source srcset="https://sentry-brand.storage.googleapis.com/sentry-logo-white.png" media="(prefers-color-scheme: dark)" />
5
- <source srcset="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" />
6
- <img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" alt="Sentry" width="280">
7
- </picture>
8
- </a>
9
- </p>
1
+ <div align="center">
2
+ <a href="https://sentry.io/?utm_source=github&utm_medium=logo" target="_blank">
3
+ <img src="https://sentry-brand.storage.googleapis.com/github-banners/github-sdk-react.jpg" alt="Sentry for React Native">
4
+ </a>
5
+ </div>
10
6
 
11
7
  _Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us [<kbd>**Check out our open positions**</kbd>](https://sentry.io/careers/)_
12
8
 
package/RNSentry.podspec CHANGED
@@ -37,7 +37,7 @@ Pod::Spec.new do |s|
37
37
 
38
38
  s.compiler_flags = other_cflags
39
39
 
40
- s.dependency 'Sentry/HybridSDK', '8.37.0'
40
+ s.dependency 'Sentry/HybridSDK', '8.40.1'
41
41
 
42
42
  if defined? install_modules_dependencies
43
43
  # Default React Native dependencies for 0.71 and above (new and legacy architecture)
@@ -54,5 +54,5 @@ android {
54
54
 
55
55
  dependencies {
56
56
  implementation 'com.facebook.react:react-native:+'
57
- api 'io.sentry:sentry-android:7.15.0'
57
+ api 'io.sentry:sentry-android:7.17.0'
58
58
  }
@@ -7,13 +7,17 @@ import java.util.Map;
7
7
  import org.jetbrains.annotations.NotNull;
8
8
  import org.jetbrains.annotations.Nullable;
9
9
 
10
- public class RNSentryBreadcrumb {
10
+ public final class RNSentryBreadcrumb {
11
+
12
+ private RNSentryBreadcrumb() {
13
+ throw new AssertionError("Utility class should not be instantiated");
14
+ }
11
15
 
12
16
  @Nullable
13
17
  public static String getCurrentScreenFrom(ReadableMap from) {
14
18
  final @Nullable String maybeCategory =
15
19
  from.hasKey("category") ? from.getString("category") : null;
16
- if (maybeCategory == null || !maybeCategory.equals("navigation")) {
20
+ if (maybeCategory == null || !"navigation".equals(maybeCategory)) {
17
21
  return null;
18
22
  }
19
23
 
@@ -26,7 +30,7 @@ public class RNSentryBreadcrumb {
26
30
  // getString might throw if cast to string fails (data.to is not enforced by TS to be a
27
31
  // string)
28
32
  return maybeData.hasKey("to") ? maybeData.getString("to") : null;
29
- } catch (Throwable exception) {
33
+ } catch (Throwable exception) { // NOPMD - We don't want to crash in any case
30
34
  return null;
31
35
  }
32
36
  }
@@ -14,11 +14,15 @@ import java.util.List;
14
14
  import java.util.Map;
15
15
  import org.jetbrains.annotations.Nullable;
16
16
 
17
- public class RNSentryMapConverter {
17
+ public final class RNSentryMapConverter {
18
18
  public static final String NAME = "RNSentry.MapConverter";
19
19
 
20
20
  private static final ILogger logger = new AndroidLogger(NAME);
21
21
 
22
+ private RNSentryMapConverter() {
23
+ throw new AssertionError("Utility class should not be instantiated");
24
+ }
25
+
22
26
  public static Object convertToWritable(@Nullable Object serialized) {
23
27
  if (serialized instanceof List) {
24
28
  WritableArray writable = Arguments.createArray();
@@ -20,11 +20,13 @@ import com.facebook.react.bridge.Promise;
20
20
  import com.facebook.react.bridge.ReactApplicationContext;
21
21
  import com.facebook.react.bridge.ReadableMap;
22
22
  import com.facebook.react.bridge.ReadableMapKeySetIterator;
23
+ import com.facebook.react.bridge.ReadableType;
23
24
  import com.facebook.react.bridge.UiThreadUtil;
24
25
  import com.facebook.react.bridge.WritableArray;
25
26
  import com.facebook.react.bridge.WritableMap;
26
27
  import com.facebook.react.bridge.WritableNativeArray;
27
28
  import com.facebook.react.bridge.WritableNativeMap;
29
+ import com.facebook.react.common.JavascriptException;
28
30
  import com.facebook.react.modules.core.DeviceEventManagerModule;
29
31
  import io.sentry.HubAdapter;
30
32
  import io.sentry.ILogger;
@@ -57,7 +59,6 @@ import io.sentry.android.core.internal.debugmeta.AssetsDebugMetaLoader;
57
59
  import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
58
60
  import io.sentry.android.core.performance.AppStartMetrics;
59
61
  import io.sentry.protocol.SdkVersion;
60
- import io.sentry.protocol.SentryException;
61
62
  import io.sentry.protocol.SentryId;
62
63
  import io.sentry.protocol.SentryPackage;
63
64
  import io.sentry.protocol.User;
@@ -91,7 +92,7 @@ public class RNSentryModuleImpl {
91
92
  private static final ILogger logger = new AndroidLogger(NAME);
92
93
  private static final BuildInfoProvider buildInfo = new BuildInfoProvider(logger);
93
94
  private static final String modulesPath = "modules.json";
94
- private static final Charset UTF_8 = Charset.forName("UTF-8");
95
+ private static final Charset UTF_8 = Charset.forName("UTF-8"); // NOPMD - Allow using UTF-8
95
96
 
96
97
  private final ReactApplicationContext reactApplicationContext;
97
98
  private final PackageInfo packageInfo;
@@ -126,10 +127,13 @@ public class RNSentryModuleImpl {
126
127
  /** Max trace file size in bytes. */
127
128
  private long maxTraceFileSize = 5 * 1024 * 1024;
128
129
 
130
+ private final @NotNull SentryDateProvider dateProvider;
131
+
129
132
  public RNSentryModuleImpl(ReactApplicationContext reactApplicationContext) {
130
133
  packageInfo = getPackageInfo(reactApplicationContext);
131
134
  this.reactApplicationContext = reactApplicationContext;
132
135
  this.emitNewFrameEvent = createEmitNewFrameEvent();
136
+ this.dateProvider = new SentryAndroidDateProvider();
133
137
  }
134
138
 
135
139
  private ReactApplicationContext getReactApplicationContext() {
@@ -141,8 +145,6 @@ public class RNSentryModuleImpl {
141
145
  }
142
146
 
143
147
  private @NotNull Runnable createEmitNewFrameEvent() {
144
- final @NotNull SentryDateProvider dateProvider = new SentryAndroidDateProvider();
145
-
146
148
  return () -> {
147
149
  final SentryDate endDate = dateProvider.now();
148
150
  WritableMap event = Arguments.createMap();
@@ -174,135 +176,136 @@ public class RNSentryModuleImpl {
174
176
  public void initNativeSdk(final ReadableMap rnOptions, Promise promise) {
175
177
  SentryAndroid.init(
176
178
  this.getReactApplicationContext(),
177
- options -> {
178
- @Nullable SdkVersion sdkVersion = options.getSdkVersion();
179
- if (sdkVersion == null) {
180
- sdkVersion = new SdkVersion(ANDROID_SDK_NAME, BuildConfig.VERSION_NAME);
181
- } else {
182
- sdkVersion.setName(ANDROID_SDK_NAME);
183
- }
179
+ options -> getSentryAndroidOptions(options, rnOptions, logger));
184
180
 
185
- options.setSentryClientName(sdkVersion.getName() + "/" + sdkVersion.getVersion());
186
- options.setNativeSdkName(NATIVE_SDK_NAME);
187
- options.setSdkVersion(sdkVersion);
181
+ promise.resolve(true);
182
+ }
188
183
 
189
- if (rnOptions.hasKey("debug") && rnOptions.getBoolean("debug")) {
190
- options.setDebug(true);
191
- }
192
- if (rnOptions.hasKey("dsn") && rnOptions.getString("dsn") != null) {
193
- String dsn = rnOptions.getString("dsn");
194
- logger.log(SentryLevel.INFO, String.format("Starting with DSN: '%s'", dsn));
195
- options.setDsn(dsn);
196
- } else {
197
- // SentryAndroid needs an empty string fallback for the dsn.
198
- options.setDsn("");
199
- }
200
- if (rnOptions.hasKey("sampleRate")) {
201
- options.setSampleRate(rnOptions.getDouble("sampleRate"));
202
- }
203
- if (rnOptions.hasKey("sendClientReports")) {
204
- options.setSendClientReports(rnOptions.getBoolean("sendClientReports"));
205
- }
206
- if (rnOptions.hasKey("maxBreadcrumbs")) {
207
- options.setMaxBreadcrumbs(rnOptions.getInt("maxBreadcrumbs"));
208
- }
209
- if (rnOptions.hasKey("maxCacheItems")) {
210
- options.setMaxCacheItems(rnOptions.getInt("maxCacheItems"));
211
- }
212
- if (rnOptions.hasKey("environment") && rnOptions.getString("environment") != null) {
213
- options.setEnvironment(rnOptions.getString("environment"));
214
- }
215
- if (rnOptions.hasKey("release") && rnOptions.getString("release") != null) {
216
- options.setRelease(rnOptions.getString("release"));
217
- }
218
- if (rnOptions.hasKey("dist") && rnOptions.getString("dist") != null) {
219
- options.setDist(rnOptions.getString("dist"));
220
- }
221
- if (rnOptions.hasKey("enableAutoSessionTracking")) {
222
- options.setEnableAutoSessionTracking(rnOptions.getBoolean("enableAutoSessionTracking"));
223
- }
224
- if (rnOptions.hasKey("sessionTrackingIntervalMillis")) {
225
- options.setSessionTrackingIntervalMillis(
226
- rnOptions.getInt("sessionTrackingIntervalMillis"));
227
- }
228
- if (rnOptions.hasKey("shutdownTimeout")) {
229
- options.setShutdownTimeoutMillis(rnOptions.getInt("shutdownTimeout"));
230
- }
231
- if (rnOptions.hasKey("enableNdkScopeSync")) {
232
- options.setEnableScopeSync(rnOptions.getBoolean("enableNdkScopeSync"));
233
- }
234
- if (rnOptions.hasKey("attachStacktrace")) {
235
- options.setAttachStacktrace(rnOptions.getBoolean("attachStacktrace"));
236
- }
237
- if (rnOptions.hasKey("attachThreads")) {
238
- // JS use top level stacktrace and android attaches Threads which hides them so
239
- // by default we hide.
240
- options.setAttachThreads(rnOptions.getBoolean("attachThreads"));
241
- }
242
- if (rnOptions.hasKey("attachScreenshot")) {
243
- options.setAttachScreenshot(rnOptions.getBoolean("attachScreenshot"));
244
- }
245
- if (rnOptions.hasKey("attachViewHierarchy")) {
246
- options.setAttachViewHierarchy(rnOptions.getBoolean("attachViewHierarchy"));
247
- }
248
- if (rnOptions.hasKey("sendDefaultPii")) {
249
- options.setSendDefaultPii(rnOptions.getBoolean("sendDefaultPii"));
250
- }
251
- if (rnOptions.hasKey("maxQueueSize")) {
252
- options.setMaxQueueSize(rnOptions.getInt("maxQueueSize"));
253
- }
254
- if (rnOptions.hasKey("enableNdk")) {
255
- options.setEnableNdk(rnOptions.getBoolean("enableNdk"));
256
- }
257
- if (rnOptions.hasKey("_experiments")) {
258
- options.getExperimental().setSessionReplay(getReplayOptions(rnOptions));
259
- options
260
- .getReplayController()
261
- .setBreadcrumbConverter(new RNSentryReplayBreadcrumbConverter());
262
- }
263
- options.setBeforeSend(
264
- (event, hint) -> {
265
- // React native internally throws a JavascriptException
266
- // Since we catch it before that, we don't want to send this one
267
- // because we would send it twice
268
- try {
269
- SentryException ex = event.getExceptions().get(0);
270
- if (null != ex && ex.getType().contains("JavascriptException")) {
271
- return null;
272
- }
273
- } catch (Throwable ignored) {
274
- // We do nothing
275
- }
184
+ protected void getSentryAndroidOptions(
185
+ @NotNull SentryAndroidOptions options, @NotNull ReadableMap rnOptions, ILogger logger) {
186
+ @Nullable SdkVersion sdkVersion = options.getSdkVersion();
187
+ if (sdkVersion == null) {
188
+ sdkVersion = new SdkVersion(ANDROID_SDK_NAME, BuildConfig.VERSION_NAME);
189
+ } else {
190
+ sdkVersion.setName(ANDROID_SDK_NAME);
191
+ }
192
+
193
+ options.setSentryClientName(sdkVersion.getName() + "/" + sdkVersion.getVersion());
194
+ options.setNativeSdkName(NATIVE_SDK_NAME);
195
+ options.setSdkVersion(sdkVersion);
196
+
197
+ if (rnOptions.hasKey("debug") && rnOptions.getBoolean("debug")) {
198
+ options.setDebug(true);
199
+ }
200
+ if (rnOptions.hasKey("dsn") && rnOptions.getString("dsn") != null) {
201
+ String dsn = rnOptions.getString("dsn");
202
+ logger.log(SentryLevel.INFO, String.format("Starting with DSN: '%s'", dsn));
203
+ options.setDsn(dsn);
204
+ } else {
205
+ // SentryAndroid needs an empty string fallback for the dsn.
206
+ options.setDsn("");
207
+ }
208
+ if (rnOptions.hasKey("sampleRate")) {
209
+ options.setSampleRate(rnOptions.getDouble("sampleRate"));
210
+ }
211
+ if (rnOptions.hasKey("sendClientReports")) {
212
+ options.setSendClientReports(rnOptions.getBoolean("sendClientReports"));
213
+ }
214
+ if (rnOptions.hasKey("maxBreadcrumbs")) {
215
+ options.setMaxBreadcrumbs(rnOptions.getInt("maxBreadcrumbs"));
216
+ }
217
+ if (rnOptions.hasKey("maxCacheItems")) {
218
+ options.setMaxCacheItems(rnOptions.getInt("maxCacheItems"));
219
+ }
220
+ if (rnOptions.hasKey("environment") && rnOptions.getString("environment") != null) {
221
+ options.setEnvironment(rnOptions.getString("environment"));
222
+ }
223
+ if (rnOptions.hasKey("release") && rnOptions.getString("release") != null) {
224
+ options.setRelease(rnOptions.getString("release"));
225
+ }
226
+ if (rnOptions.hasKey("dist") && rnOptions.getString("dist") != null) {
227
+ options.setDist(rnOptions.getString("dist"));
228
+ }
229
+ if (rnOptions.hasKey("enableAutoSessionTracking")) {
230
+ options.setEnableAutoSessionTracking(rnOptions.getBoolean("enableAutoSessionTracking"));
231
+ }
232
+ if (rnOptions.hasKey("sessionTrackingIntervalMillis")) {
233
+ options.setSessionTrackingIntervalMillis(rnOptions.getInt("sessionTrackingIntervalMillis"));
234
+ }
235
+ if (rnOptions.hasKey("shutdownTimeout")) {
236
+ options.setShutdownTimeoutMillis(rnOptions.getInt("shutdownTimeout"));
237
+ }
238
+ if (rnOptions.hasKey("enableNdkScopeSync")) {
239
+ options.setEnableScopeSync(rnOptions.getBoolean("enableNdkScopeSync"));
240
+ }
241
+ if (rnOptions.hasKey("attachStacktrace")) {
242
+ options.setAttachStacktrace(rnOptions.getBoolean("attachStacktrace"));
243
+ }
244
+ if (rnOptions.hasKey("attachThreads")) {
245
+ // JS use top level stacktrace and android attaches Threads which hides them so
246
+ // by default we hide.
247
+ options.setAttachThreads(rnOptions.getBoolean("attachThreads"));
248
+ }
249
+ if (rnOptions.hasKey("attachScreenshot")) {
250
+ options.setAttachScreenshot(rnOptions.getBoolean("attachScreenshot"));
251
+ }
252
+ if (rnOptions.hasKey("attachViewHierarchy")) {
253
+ options.setAttachViewHierarchy(rnOptions.getBoolean("attachViewHierarchy"));
254
+ }
255
+ if (rnOptions.hasKey("sendDefaultPii")) {
256
+ options.setSendDefaultPii(rnOptions.getBoolean("sendDefaultPii"));
257
+ }
258
+ if (rnOptions.hasKey("maxQueueSize")) {
259
+ options.setMaxQueueSize(rnOptions.getInt("maxQueueSize"));
260
+ }
261
+ if (rnOptions.hasKey("enableNdk")) {
262
+ options.setEnableNdk(rnOptions.getBoolean("enableNdk"));
263
+ }
264
+ if (rnOptions.hasKey("spotlight")) {
265
+ if (rnOptions.getType("spotlight") == ReadableType.Boolean) {
266
+ options.setEnableSpotlight(rnOptions.getBoolean("spotlight"));
267
+ options.setSpotlightConnectionUrl(rnOptions.getString("defaultSidecarUrl"));
268
+ } else if (rnOptions.getType("spotlight") == ReadableType.String) {
269
+ options.setEnableSpotlight(true);
270
+ options.setSpotlightConnectionUrl(rnOptions.getString("spotlight"));
271
+ }
272
+ }
273
+ if (rnOptions.hasKey("_experiments")) {
274
+ options.getExperimental().setSessionReplay(getReplayOptions(rnOptions));
275
+ options.getReplayController().setBreadcrumbConverter(new RNSentryReplayBreadcrumbConverter());
276
+ }
276
277
 
277
- setEventOriginTag(event);
278
- addPackages(event, options.getSdkVersion());
278
+ // React native internally throws a JavascriptException.
279
+ // we want to ignore it on the native side to avoid sending it twice.
280
+ options.addIgnoredExceptionForType(JavascriptException.class);
279
281
 
280
- return event;
281
- });
282
+ options.setBeforeSend(
283
+ (event, hint) -> {
284
+ setEventOriginTag(event);
285
+ addPackages(event, options.getSdkVersion());
282
286
 
283
- if (rnOptions.hasKey("enableNativeCrashHandling")
284
- && !rnOptions.getBoolean("enableNativeCrashHandling")) {
285
- final List<Integration> integrations = options.getIntegrations();
286
- for (final Integration integration : integrations) {
287
- if (integration instanceof UncaughtExceptionHandlerIntegration
288
- || integration instanceof AnrIntegration
289
- || integration instanceof NdkIntegration) {
290
- integrations.remove(integration);
291
- }
292
- }
293
- }
294
- logger.log(
295
- SentryLevel.INFO,
296
- String.format("Native Integrations '%s'", options.getIntegrations()));
297
-
298
- final CurrentActivityHolder currentActivityHolder = CurrentActivityHolder.getInstance();
299
- final Activity currentActivity = getCurrentActivity();
300
- if (currentActivity != null) {
301
- currentActivityHolder.setActivity(currentActivity);
302
- }
287
+ return event;
303
288
  });
304
289
 
305
- promise.resolve(true);
290
+ if (rnOptions.hasKey("enableNativeCrashHandling")
291
+ && !rnOptions.getBoolean("enableNativeCrashHandling")) {
292
+ final List<Integration> integrations = options.getIntegrations();
293
+ for (final Integration integration : integrations) {
294
+ if (integration instanceof UncaughtExceptionHandlerIntegration
295
+ || integration instanceof AnrIntegration
296
+ || integration instanceof NdkIntegration) {
297
+ integrations.remove(integration);
298
+ }
299
+ }
300
+ }
301
+ logger.log(
302
+ SentryLevel.INFO, String.format("Native Integrations '%s'", options.getIntegrations()));
303
+
304
+ final CurrentActivityHolder currentActivityHolder = CurrentActivityHolder.getInstance();
305
+ final Activity currentActivity = getCurrentActivity();
306
+ if (currentActivity != null) {
307
+ currentActivityHolder.setActivity(currentActivity);
308
+ }
306
309
  }
307
310
 
308
311
  private SentryReplayOptions getReplayOptions(@NotNull ReadableMap rnOptions) {
@@ -356,12 +359,12 @@ public class RNSentryModuleImpl {
356
359
  throw new RuntimeException("TEST - Sentry Client Crash (only works in release mode)");
357
360
  }
358
361
 
359
- public void addListener(String _eventType) {
362
+ public void addListener(String eventType) {
360
363
  // Is must be defined otherwise the generated interface from TS won't be fulfilled
361
364
  logger.log(SentryLevel.ERROR, "addListener of NativeEventEmitter can't be used on Android!");
362
365
  }
363
366
 
364
- public void removeListeners(double _id) {
367
+ public void removeListeners(double id) {
365
368
  // Is must be defined otherwise the generated interface from TS won't be fulfilled
366
369
  logger.log(
367
370
  SentryLevel.ERROR, "removeListeners of NativeEventEmitter can't be used on Android!");
@@ -369,17 +372,16 @@ public class RNSentryModuleImpl {
369
372
 
370
373
  public void fetchModules(Promise promise) {
371
374
  final AssetManager assets = this.getReactApplicationContext().getResources().getAssets();
372
- try (final InputStream stream =
373
- new BufferedInputStream(assets.open(RNSentryModuleImpl.modulesPath))) {
375
+ try (InputStream stream = new BufferedInputStream(assets.open(modulesPath))) {
374
376
  int size = stream.available();
375
377
  byte[] buffer = new byte[size];
376
378
  stream.read(buffer);
377
379
  stream.close();
378
- String modulesJson = new String(buffer, RNSentryModuleImpl.UTF_8);
380
+ String modulesJson = new String(buffer, UTF_8);
379
381
  promise.resolve(modulesJson);
380
382
  } catch (FileNotFoundException e) {
381
383
  promise.resolve(null);
382
- } catch (Throwable e) {
384
+ } catch (Throwable e) { // NOPMD - We don't want to crash in any case
383
385
  logger.log(SentryLevel.WARNING, "Fetching JS Modules failed.");
384
386
  promise.resolve(null);
385
387
  }
@@ -462,7 +464,7 @@ public class RNSentryModuleImpl {
462
464
  map.putInt("frozenFrames", frozenFrames);
463
465
 
464
466
  promise.resolve(map);
465
- } catch (Throwable ignored) {
467
+ } catch (Throwable ignored) { // NOPMD - We don't want to crash in any case
466
468
  logger.log(SentryLevel.WARNING, "Error fetching native frames.");
467
469
  promise.resolve(null);
468
470
  }
@@ -493,7 +495,7 @@ public class RNSentryModuleImpl {
493
495
  try {
494
496
  InternalSentrySdk.captureEnvelope(
495
497
  bytes, !options.hasKey("hardCrashed") || !options.getBoolean("hardCrashed"));
496
- } catch (Throwable e) {
498
+ } catch (Throwable e) { // NOPMD - We don't want to crash in any case
497
499
  logger.log(SentryLevel.ERROR, "Error while capturing envelope");
498
500
  promise.resolve(false);
499
501
  }
@@ -511,7 +513,7 @@ public class RNSentryModuleImpl {
511
513
 
512
514
  final byte[] raw = takeScreenshotOnUiThread(activity);
513
515
 
514
- if (raw == null) {
516
+ if (raw == null || raw.length == 0) {
515
517
  logger.log(SentryLevel.WARNING, "Screenshot is null, screen was not captured.");
516
518
  promise.resolve(null);
517
519
  return;
@@ -550,7 +552,7 @@ public class RNSentryModuleImpl {
550
552
  doneSignal.await(SCREENSHOT_TIMEOUT_SECONDS, SECONDS);
551
553
  } catch (InterruptedException e) {
552
554
  logger.log(SentryLevel.ERROR, "Screenshot process was interrupted.");
553
- return null;
555
+ return new byte[0];
554
556
  }
555
557
 
556
558
  return bytesWrapper[0];
@@ -627,7 +629,7 @@ public class RNSentryModuleImpl {
627
629
  }
628
630
 
629
631
  if (userDataKeys != null) {
630
- HashMap<String, String> userDataMap = new HashMap<>();
632
+ Map<String, String> userDataMap = new HashMap<>();
631
633
  ReadableMapKeySetIterator it = userDataKeys.keySetIterator();
632
634
  while (it.hasNextKey()) {
633
635
  String key = it.nextKey();
@@ -694,7 +696,7 @@ public class RNSentryModuleImpl {
694
696
  return;
695
697
  }
696
698
 
697
- final HashMap<String, Object> contextHashMap = context.toHashMap();
699
+ final Map<String, Object> contextHashMap = context.toHashMap();
698
700
  scope.setContexts(key, contextHashMap);
699
701
  });
700
702
  }
@@ -726,7 +728,7 @@ public class RNSentryModuleImpl {
726
728
  frameMetricsAggregator.add(currentActivity);
727
729
 
728
730
  logger.log(SentryLevel.INFO, "FrameMetricsAggregator installed.");
729
- } catch (Throwable ignored) {
731
+ } catch (Throwable ignored) { // NOPMD - We don't want to crash in any case
730
732
  // throws ConcurrentModification when calling addOnFrameMetricsAvailableListener
731
733
  // this is a best effort since we can't reproduce it
732
734
  logger.log(SentryLevel.ERROR, "Error adding Activity to frameMetricsAggregator.");
@@ -746,6 +748,10 @@ public class RNSentryModuleImpl {
746
748
  }
747
749
  }
748
750
 
751
+ public void getNewScreenTimeToDisplay(Promise promise) {
752
+ RNSentryTimeToDisplay.getTimeToDisplay(promise, dateProvider);
753
+ }
754
+
749
755
  private String getProfilingTracesDirPath() {
750
756
  if (cacheDirPath == null) {
751
757
  cacheDirPath =
@@ -785,7 +791,7 @@ public class RNSentryModuleImpl {
785
791
  }
786
792
 
787
793
  result.putBoolean("started", true);
788
- } catch (Throwable e) {
794
+ } catch (Throwable e) { // NOPMD - We don't want to crash in any case
789
795
  result.putBoolean("started", false);
790
796
  result.putString("error", e.toString());
791
797
  }
@@ -825,7 +831,7 @@ public class RNSentryModuleImpl {
825
831
  androidProfile.putString("build_id", getProguardUuid());
826
832
  result.putMap("androidProfile", androidProfile);
827
833
  }
828
- } catch (Throwable e) {
834
+ } catch (Throwable e) { // NOPMD - We don't want to crash in any case
829
835
  result.putString("error", e.toString());
830
836
  } finally {
831
837
  if (output != null) {
@@ -834,7 +840,7 @@ public class RNSentryModuleImpl {
834
840
  if (!wasProfileSuccessfullyDeleted) {
835
841
  logger.log(SentryLevel.WARNING, "Profile not deleted from:" + output.getAbsolutePath());
836
842
  }
837
- } catch (Throwable e) {
843
+ } catch (Throwable e) { // NOPMD - We don't want to crash in any case
838
844
  logger.log(SentryLevel.WARNING, "Profile not deleted from:" + output.getAbsolutePath());
839
845
  }
840
846
  }
@@ -848,7 +854,7 @@ public class RNSentryModuleImpl {
848
854
  }
849
855
  isProguardDebugMetaLoaded = true;
850
856
  final @Nullable List<Properties> debugMetaList =
851
- (new AssetsDebugMetaLoader(this.getReactApplicationContext(), logger)).loadDebugMeta();
857
+ new AssetsDebugMetaLoader(this.getReactApplicationContext(), logger).loadDebugMeta();
852
858
  if (debugMetaList == null) {
853
859
  return null;
854
860
  }
@@ -866,7 +872,7 @@ public class RNSentryModuleImpl {
866
872
  }
867
873
 
868
874
  private String readStringFromFile(File path) throws IOException {
869
- try (final BufferedReader br = new BufferedReader(new FileReader(path)); ) {
875
+ try (BufferedReader br = new BufferedReader(new FileReader(path)); ) {
870
876
 
871
877
  final StringBuilder text = new StringBuilder();
872
878
  String line;
@@ -943,7 +949,7 @@ public class RNSentryModuleImpl {
943
949
  private void addPackages(SentryEvent event, SdkVersion sdk) {
944
950
  SdkVersion eventSdk = event.getSdk();
945
951
  if (eventSdk != null
946
- && eventSdk.getName().equals("sentry.javascript.react-native")
952
+ && "sentry.javascript.react-native".equals(eventSdk.getName())
947
953
  && sdk != null) {
948
954
  List<SentryPackage> sentryPackages = sdk.getPackages();
949
955
  if (sentryPackages != null) {
@@ -40,7 +40,7 @@ public class RNSentryReactFragmentLifecycleTracer extends FragmentLifecycleCallb
40
40
  @NotNull Fragment f,
41
41
  @NotNull View v,
42
42
  @Nullable Bundle savedInstanceState) {
43
- if (!("com.swmansion.rnscreens.ScreenStackFragment".equals(f.getClass().getCanonicalName()))) {
43
+ if (!"com.swmansion.rnscreens.ScreenStackFragment".equals(f.getClass().getCanonicalName())) {
44
44
  logger.log(
45
45
  SentryLevel.DEBUG,
46
46
  "Fragment is not a ScreenStackFragment, won't listen for the first draw.");
@@ -13,8 +13,6 @@ import org.jetbrains.annotations.Nullable;
13
13
  import org.jetbrains.annotations.TestOnly;
14
14
 
15
15
  public final class RNSentryReplayBreadcrumbConverter extends DefaultReplayBreadcrumbConverter {
16
- public RNSentryReplayBreadcrumbConverter() {}
17
-
18
16
  @Override
19
17
  public @Nullable RRWebEvent convert(final @NotNull Breadcrumb breadcrumb) {
20
18
  if (breadcrumb.getCategory() == null) {
@@ -22,22 +20,22 @@ public final class RNSentryReplayBreadcrumbConverter extends DefaultReplayBreadc
22
20
  }
23
21
 
24
22
  // Do not add Sentry Event breadcrumbs to replay
25
- if (breadcrumb.getCategory().equals("sentry.event")
26
- || breadcrumb.getCategory().equals("sentry.transaction")) {
23
+ if ("sentry.event".equals(breadcrumb.getCategory())
24
+ || "sentry.transaction".equals(breadcrumb.getCategory())) {
27
25
  return null;
28
26
  }
29
- if (breadcrumb.getCategory().equals("http")) {
27
+ if ("http".equals(breadcrumb.getCategory())) {
30
28
  // Drop native http breadcrumbs to avoid duplicates
31
29
  return null;
32
30
  }
33
31
 
34
- if (breadcrumb.getCategory().equals("touch")) {
32
+ if ("touch".equals(breadcrumb.getCategory())) {
35
33
  return convertTouchBreadcrumb(breadcrumb);
36
34
  }
37
- if (breadcrumb.getCategory().equals("navigation")) {
35
+ if ("navigation".equals(breadcrumb.getCategory())) {
38
36
  return convertNavigationBreadcrumb(breadcrumb);
39
37
  }
40
- if (breadcrumb.getCategory().equals("xhr")) {
38
+ if ("xhr".equals(breadcrumb.getCategory())) {
41
39
  return convertNetworkBreadcrumb(breadcrumb);
42
40
  }
43
41
 
@@ -46,8 +44,7 @@ public final class RNSentryReplayBreadcrumbConverter extends DefaultReplayBreadc
46
44
  // ignore native navigation breadcrumbs
47
45
  if (nativeBreadcrumb instanceof RRWebBreadcrumbEvent) {
48
46
  final RRWebBreadcrumbEvent rrWebBreadcrumb = (RRWebBreadcrumbEvent) nativeBreadcrumb;
49
- if (rrWebBreadcrumb.getCategory() != null
50
- && rrWebBreadcrumb.getCategory().equals("navigation")) {
47
+ if ("navigation".equals(rrWebBreadcrumb.getCategory())) {
51
48
  return null;
52
49
  }
53
50
  }
@@ -69,8 +66,7 @@ public final class RNSentryReplayBreadcrumbConverter extends DefaultReplayBreadc
69
66
 
70
67
  rrWebBreadcrumb.setCategory("ui.tap");
71
68
 
72
- rrWebBreadcrumb.setMessage(
73
- RNSentryReplayBreadcrumbConverter.getTouchPathMessage(breadcrumb.getData("path")));
69
+ rrWebBreadcrumb.setMessage(getTouchPathMessage(breadcrumb.getData("path")));
74
70
 
75
71
  setRRWebEventDefaultsFrom(rrWebBreadcrumb, breadcrumb);
76
72
  return rrWebBreadcrumb;
@@ -83,7 +79,7 @@ public final class RNSentryReplayBreadcrumbConverter extends DefaultReplayBreadc
83
79
  }
84
80
 
85
81
  final @NotNull List path = (List) maybePath;
86
- if (path.size() == 0) {
82
+ if (path.isEmpty()) {
87
83
  return null;
88
84
  }
89
85
 
@@ -145,7 +141,7 @@ public final class RNSentryReplayBreadcrumbConverter extends DefaultReplayBreadc
145
141
  return null;
146
142
  }
147
143
 
148
- final HashMap<String, Object> data = new HashMap<>();
144
+ final Map<String, Object> data = new HashMap<>();
149
145
  if (breadcrumb.getData("method") instanceof String) {
150
146
  data.put("method", breadcrumb.getData("method"));
151
147
  }