@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.
- package/README.md +5 -9
- package/RNSentry.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryBreadcrumb.java +7 -3
- package/android/src/main/java/io/sentry/react/RNSentryMapConverter.java +5 -1
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +151 -145
- package/android/src/main/java/io/sentry/react/RNSentryReactFragmentLifecycleTracer.java +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryReplayBreadcrumbConverter.java +10 -14
- package/android/src/main/java/io/sentry/react/RNSentryTimeToDisplay.java +42 -0
- package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +5 -0
- package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +5 -0
- package/dist/js/NativeRNSentry.d.ts +1 -0
- package/dist/js/NativeRNSentry.d.ts.map +1 -1
- package/dist/js/NativeRNSentry.js.map +1 -1
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +5 -2
- package/dist/js/client.js.map +1 -1
- package/dist/js/index.d.ts +2 -2
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +1 -1
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/spotlight.d.ts +4 -0
- package/dist/js/integrations/spotlight.d.ts.map +1 -1
- package/dist/js/integrations/spotlight.js +4 -1
- package/dist/js/integrations/spotlight.js.map +1 -1
- package/dist/js/tracing/reactnavigation.js +7 -7
- package/dist/js/tracing/reactnavigation.js.map +1 -1
- package/dist/js/utils/ignorerequirecyclelogs.d.ts +6 -1
- package/dist/js/utils/ignorerequirecyclelogs.d.ts.map +1 -1
- package/dist/js/utils/ignorerequirecyclelogs.js +6 -2
- package/dist/js/utils/ignorerequirecyclelogs.js.map +1 -1
- package/dist/js/utils/sentryeventemitterfallback.d.ts +19 -0
- package/dist/js/utils/sentryeventemitterfallback.d.ts.map +1 -0
- package/dist/js/utils/sentryeventemitterfallback.js +78 -0
- package/dist/js/utils/sentryeventemitterfallback.js.map +1 -0
- package/dist/js/vendor/react-native/index.d.ts +1 -1
- package/dist/js/vendor/react-native/index.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts +3 -0
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +6 -0
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.h +8 -12
- package/ios/RNSentry.mm +382 -303
- package/ios/RNSentryBreadcrumb.h +2 -2
- package/ios/RNSentryBreadcrumb.m +7 -6
- package/ios/RNSentryDependencyContainer.h +2 -2
- package/ios/RNSentryDependencyContainer.m +7 -6
- package/ios/RNSentryFramesTrackerListener.h +6 -6
- package/ios/RNSentryFramesTrackerListener.m +10 -8
- package/ios/RNSentryId.m +2 -1
- package/ios/RNSentryOnDrawReporter.h +5 -5
- package/ios/RNSentryOnDrawReporter.m +26 -24
- package/ios/RNSentryRNSScreen.h +1 -1
- package/ios/RNSentryRNSScreen.m +18 -18
- package/ios/RNSentryReplay.m +42 -53
- package/ios/RNSentryReplayBreadcrumbConverter.h +3 -4
- package/ios/RNSentryReplayBreadcrumbConverter.m +139 -132
- package/ios/RNSentryTimeToDisplay.h +7 -0
- package/ios/RNSentryTimeToDisplay.m +44 -0
- package/package.json +16 -15
- package/plugin/build/utils.js +6 -6
- package/plugin/build/withSentry.js +2 -2
- package/plugin/build/withSentryAndroid.js +2 -2
- package/plugin/build/withSentryIOS.js +3 -3
- package/scripts/sentry-xcode-debug-files.sh +2 -0
- package/sentry.gradle +10 -2
- package/src/js/NativeRNSentry.ts +1 -0
- package/ts3.8/dist/js/NativeRNSentry.d.ts +1 -0
- package/ts3.8/dist/js/index.d.ts +2 -2
- package/ts3.8/dist/js/integrations/spotlight.d.ts +4 -0
- package/ts3.8/dist/js/utils/ignorerequirecyclelogs.d.ts +6 -1
- package/ts3.8/dist/js/utils/sentryeventemitterfallback.d.ts +19 -0
- package/ts3.8/dist/js/vendor/react-native/index.d.ts +1 -1
- package/ts3.8/dist/js/version.d.ts +1 -1
- package/ts3.8/dist/js/wrapper.d.ts +3 -0
package/README.md
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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.
|
|
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)
|
package/android/build.gradle
CHANGED
|
@@ -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 || !
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
options.setSdkVersion(sdkVersion);
|
|
181
|
+
promise.resolve(true);
|
|
182
|
+
}
|
|
188
183
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
278
|
-
|
|
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
|
-
|
|
281
|
-
|
|
282
|
+
options.setBeforeSend(
|
|
283
|
+
(event, hint) -> {
|
|
284
|
+
setEventOriginTag(event);
|
|
285
|
+
addPackages(event, options.getSdkVersion());
|
|
282
286
|
|
|
283
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 (
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 (
|
|
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
|
-
&&
|
|
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 (!
|
|
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 (
|
|
26
|
-
||
|
|
23
|
+
if ("sentry.event".equals(breadcrumb.getCategory())
|
|
24
|
+
|| "sentry.transaction".equals(breadcrumb.getCategory())) {
|
|
27
25
|
return null;
|
|
28
26
|
}
|
|
29
|
-
if (breadcrumb.getCategory()
|
|
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()
|
|
32
|
+
if ("touch".equals(breadcrumb.getCategory())) {
|
|
35
33
|
return convertTouchBreadcrumb(breadcrumb);
|
|
36
34
|
}
|
|
37
|
-
if (breadcrumb.getCategory()
|
|
35
|
+
if ("navigation".equals(breadcrumb.getCategory())) {
|
|
38
36
|
return convertNavigationBreadcrumb(breadcrumb);
|
|
39
37
|
}
|
|
40
|
-
if (breadcrumb.getCategory()
|
|
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()
|
|
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.
|
|
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
|
|
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
|
}
|