@sentry/react-native 6.6.0 → 6.7.0-alpha.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/RNSentry.podspec +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryCompositeOptionsConfiguration.java +25 -0
- package/android/src/main/java/io/sentry/react/RNSentryJsonConverter.java +76 -0
- package/android/src/main/java/io/sentry/react/RNSentryJsonUtils.java +41 -0
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +2 -280
- package/android/src/main/java/io/sentry/react/RNSentrySDK.java +68 -0
- package/android/src/main/java/io/sentry/react/RNSentryStart.java +365 -0
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +21 -10
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tools/metroconfig.d.ts +9 -1
- package/dist/js/tools/metroconfig.d.ts.map +1 -1
- package/dist/js/tools/metroconfig.js +9 -2
- package/dist/js/tools/metroconfig.js.map +1 -1
- package/dist/js/tools/sentryMetroSerializer.d.ts.map +1 -1
- package/dist/js/tools/sentryMetroSerializer.js +1 -0
- package/dist/js/tools/sentryMetroSerializer.js.map +1 -1
- package/dist/js/tools/sentryOptionsSerializer.d.ts +6 -0
- package/dist/js/tools/sentryOptionsSerializer.d.ts.map +1 -0
- package/dist/js/tools/sentryOptionsSerializer.js +91 -0
- package/dist/js/tools/sentryOptionsSerializer.js.map +1 -0
- package/dist/js/tools/utils.d.ts +2 -1
- package/dist/js/tools/utils.d.ts.map +1 -1
- package/dist/js/tools/utils.js.map +1 -1
- package/dist/js/utils/worldwide.d.ts +2 -0
- package/dist/js/utils/worldwide.d.ts.map +1 -1
- package/dist/js/utils/worldwide.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.d.ts.map +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/ios/RNSentry.h +3 -5
- package/ios/RNSentry.mm +2 -169
- package/ios/RNSentrySDK.h +31 -0
- package/ios/RNSentrySDK.m +71 -0
- package/ios/RNSentryStart.h +26 -0
- package/ios/RNSentryStart.m +222 -0
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +10 -10
- package/scripts/sentry-xcode.sh +19 -0
- package/sentry.gradle +52 -1
- package/ts3.8/dist/js/utils/worldwide.d.ts +2 -0
- package/ts3.8/dist/js/version.d.ts +1 -1
package/RNSentry.podspec
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package io.sentry.react;
|
|
2
|
+
|
|
3
|
+
import io.sentry.Sentry.OptionsConfiguration;
|
|
4
|
+
import io.sentry.android.core.SentryAndroidOptions;
|
|
5
|
+
import java.util.List;
|
|
6
|
+
import org.jetbrains.annotations.NotNull;
|
|
7
|
+
|
|
8
|
+
class RNSentryCompositeOptionsConfiguration implements OptionsConfiguration<SentryAndroidOptions> {
|
|
9
|
+
private final @NotNull List<OptionsConfiguration<SentryAndroidOptions>> configurations;
|
|
10
|
+
|
|
11
|
+
@SafeVarargs
|
|
12
|
+
protected RNSentryCompositeOptionsConfiguration(
|
|
13
|
+
@NotNull OptionsConfiguration<SentryAndroidOptions>... configurations) {
|
|
14
|
+
this.configurations = List.of(configurations);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@Override
|
|
18
|
+
public void configure(@NotNull SentryAndroidOptions options) {
|
|
19
|
+
for (OptionsConfiguration<SentryAndroidOptions> configuration : configurations) {
|
|
20
|
+
if (configuration != null) {
|
|
21
|
+
configuration.configure(options);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
package io.sentry.react;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.JavaOnlyArray;
|
|
4
|
+
import com.facebook.react.bridge.JavaOnlyMap;
|
|
5
|
+
import com.facebook.react.bridge.WritableArray;
|
|
6
|
+
import com.facebook.react.bridge.WritableMap;
|
|
7
|
+
import io.sentry.ILogger;
|
|
8
|
+
import io.sentry.SentryLevel;
|
|
9
|
+
import io.sentry.android.core.AndroidLogger;
|
|
10
|
+
import java.util.Iterator;
|
|
11
|
+
import org.jetbrains.annotations.NotNull;
|
|
12
|
+
import org.jetbrains.annotations.Nullable;
|
|
13
|
+
import org.json.JSONArray;
|
|
14
|
+
import org.json.JSONException;
|
|
15
|
+
import org.json.JSONObject;
|
|
16
|
+
|
|
17
|
+
final class RNSentryJsonConverter {
|
|
18
|
+
public static final String NAME = "RNSentry.RNSentryJsonConverter";
|
|
19
|
+
|
|
20
|
+
private static final ILogger logger = new AndroidLogger(NAME);
|
|
21
|
+
|
|
22
|
+
private RNSentryJsonConverter() {
|
|
23
|
+
throw new AssertionError("Utility class should not be instantiated");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Nullable
|
|
27
|
+
static WritableMap convertToWritable(@NotNull JSONObject jsonObject) {
|
|
28
|
+
try {
|
|
29
|
+
WritableMap writableMap = new JavaOnlyMap();
|
|
30
|
+
Iterator<String> iterator = jsonObject.keys();
|
|
31
|
+
while (iterator.hasNext()) {
|
|
32
|
+
String key = iterator.next();
|
|
33
|
+
Object value = jsonObject.get(key);
|
|
34
|
+
if (value instanceof Float || value instanceof Double) {
|
|
35
|
+
writableMap.putDouble(key, jsonObject.getDouble(key));
|
|
36
|
+
} else if (value instanceof Number) {
|
|
37
|
+
writableMap.putInt(key, jsonObject.getInt(key));
|
|
38
|
+
} else if (value instanceof String) {
|
|
39
|
+
writableMap.putString(key, jsonObject.getString(key));
|
|
40
|
+
} else if (value instanceof JSONObject) {
|
|
41
|
+
writableMap.putMap(key, convertToWritable(jsonObject.getJSONObject(key)));
|
|
42
|
+
} else if (value instanceof JSONArray) {
|
|
43
|
+
writableMap.putArray(key, convertToWritable(jsonObject.getJSONArray(key)));
|
|
44
|
+
} else if (value == JSONObject.NULL) {
|
|
45
|
+
writableMap.putNull(key);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return writableMap;
|
|
49
|
+
} catch (JSONException e) {
|
|
50
|
+
logger.log(SentryLevel.ERROR, "Error parsing json object:" + e.getMessage());
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@NotNull
|
|
56
|
+
static WritableArray convertToWritable(@NotNull JSONArray jsonArray) throws JSONException {
|
|
57
|
+
WritableArray writableArray = new JavaOnlyArray();
|
|
58
|
+
for (int i = 0; i < jsonArray.length(); i++) {
|
|
59
|
+
Object value = jsonArray.get(i);
|
|
60
|
+
if (value instanceof Float || value instanceof Double) {
|
|
61
|
+
writableArray.pushDouble(jsonArray.getDouble(i));
|
|
62
|
+
} else if (value instanceof Number) {
|
|
63
|
+
writableArray.pushInt(jsonArray.getInt(i));
|
|
64
|
+
} else if (value instanceof String) {
|
|
65
|
+
writableArray.pushString(jsonArray.getString(i));
|
|
66
|
+
} else if (value instanceof JSONObject) {
|
|
67
|
+
writableArray.pushMap(convertToWritable(jsonArray.getJSONObject(i)));
|
|
68
|
+
} else if (value instanceof JSONArray) {
|
|
69
|
+
writableArray.pushArray(convertToWritable(jsonArray.getJSONArray(i)));
|
|
70
|
+
} else if (value == JSONObject.NULL) {
|
|
71
|
+
writableArray.pushNull();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return writableArray;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package io.sentry.react;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import io.sentry.ILogger;
|
|
5
|
+
import io.sentry.SentryLevel;
|
|
6
|
+
import java.io.BufferedReader;
|
|
7
|
+
import java.io.InputStream;
|
|
8
|
+
import java.io.InputStreamReader;
|
|
9
|
+
import org.jetbrains.annotations.NotNull;
|
|
10
|
+
import org.jetbrains.annotations.Nullable;
|
|
11
|
+
import org.json.JSONObject;
|
|
12
|
+
|
|
13
|
+
final class RNSentryJsonUtils {
|
|
14
|
+
private RNSentryJsonUtils() {
|
|
15
|
+
throw new AssertionError("Utility class should not be instantiated");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static @Nullable JSONObject getOptionsFromConfigurationFile(
|
|
19
|
+
@NotNull Context context, @NotNull String fileName, @NotNull ILogger logger) {
|
|
20
|
+
try (InputStream inputStream = context.getAssets().open(fileName);
|
|
21
|
+
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
|
22
|
+
|
|
23
|
+
StringBuilder stringBuilder = new StringBuilder();
|
|
24
|
+
String line;
|
|
25
|
+
while ((line = reader.readLine()) != null) {
|
|
26
|
+
stringBuilder.append(line);
|
|
27
|
+
}
|
|
28
|
+
String configFileContent = stringBuilder.toString();
|
|
29
|
+
return new JSONObject(configFileContent);
|
|
30
|
+
|
|
31
|
+
} catch (Exception e) {
|
|
32
|
+
logger.log(
|
|
33
|
+
SentryLevel.ERROR,
|
|
34
|
+
"Failed to read configuration file. Please make sure "
|
|
35
|
+
+ fileName
|
|
36
|
+
+ " exists in the root of your project.",
|
|
37
|
+
e);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -20,13 +20,11 @@ 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;
|
|
24
23
|
import com.facebook.react.bridge.UiThreadUtil;
|
|
25
24
|
import com.facebook.react.bridge.WritableArray;
|
|
26
25
|
import com.facebook.react.bridge.WritableMap;
|
|
27
26
|
import com.facebook.react.bridge.WritableNativeArray;
|
|
28
27
|
import com.facebook.react.bridge.WritableNativeMap;
|
|
29
|
-
import com.facebook.react.common.JavascriptException;
|
|
30
28
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
31
29
|
import io.sentry.Breadcrumb;
|
|
32
30
|
import io.sentry.HubAdapter;
|
|
@@ -34,25 +32,16 @@ import io.sentry.ILogger;
|
|
|
34
32
|
import io.sentry.IScope;
|
|
35
33
|
import io.sentry.ISentryExecutorService;
|
|
36
34
|
import io.sentry.ISerializer;
|
|
37
|
-
import io.sentry.Integration;
|
|
38
35
|
import io.sentry.Sentry;
|
|
39
36
|
import io.sentry.SentryDate;
|
|
40
37
|
import io.sentry.SentryDateProvider;
|
|
41
|
-
import io.sentry.SentryEvent;
|
|
42
38
|
import io.sentry.SentryExecutorService;
|
|
43
39
|
import io.sentry.SentryLevel;
|
|
44
40
|
import io.sentry.SentryOptions;
|
|
45
|
-
import io.sentry.SentryReplayOptions;
|
|
46
|
-
import io.sentry.UncaughtExceptionHandlerIntegration;
|
|
47
41
|
import io.sentry.android.core.AndroidLogger;
|
|
48
42
|
import io.sentry.android.core.AndroidProfiler;
|
|
49
|
-
import io.sentry.android.core.AnrIntegration;
|
|
50
|
-
import io.sentry.android.core.BuildConfig;
|
|
51
43
|
import io.sentry.android.core.BuildInfoProvider;
|
|
52
|
-
import io.sentry.android.core.CurrentActivityHolder;
|
|
53
44
|
import io.sentry.android.core.InternalSentrySdk;
|
|
54
|
-
import io.sentry.android.core.NdkIntegration;
|
|
55
|
-
import io.sentry.android.core.SentryAndroid;
|
|
56
45
|
import io.sentry.android.core.SentryAndroidDateProvider;
|
|
57
46
|
import io.sentry.android.core.SentryAndroidOptions;
|
|
58
47
|
import io.sentry.android.core.ViewHierarchyEventProcessor;
|
|
@@ -61,11 +50,8 @@ import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
|
|
|
61
50
|
import io.sentry.android.core.performance.AppStartMetrics;
|
|
62
51
|
import io.sentry.protocol.SdkVersion;
|
|
63
52
|
import io.sentry.protocol.SentryId;
|
|
64
|
-
import io.sentry.protocol.SentryPackage;
|
|
65
53
|
import io.sentry.protocol.User;
|
|
66
54
|
import io.sentry.protocol.ViewHierarchy;
|
|
67
|
-
import io.sentry.react.replay.RNSentryReplayMask;
|
|
68
|
-
import io.sentry.react.replay.RNSentryReplayUnmask;
|
|
69
55
|
import io.sentry.util.DebugMetaPropertiesApplier;
|
|
70
56
|
import io.sentry.util.FileUtils;
|
|
71
57
|
import io.sentry.util.JsonSerializationUtils;
|
|
@@ -77,8 +63,6 @@ import java.io.FileNotFoundException;
|
|
|
77
63
|
import java.io.FileReader;
|
|
78
64
|
import java.io.IOException;
|
|
79
65
|
import java.io.InputStream;
|
|
80
|
-
import java.net.URI;
|
|
81
|
-
import java.net.URISyntaxException;
|
|
82
66
|
import java.nio.charset.Charset;
|
|
83
67
|
import java.util.HashMap;
|
|
84
68
|
import java.util.Iterator;
|
|
@@ -178,216 +162,12 @@ public class RNSentryModuleImpl {
|
|
|
178
162
|
}
|
|
179
163
|
|
|
180
164
|
public void initNativeSdk(final ReadableMap rnOptions, Promise promise) {
|
|
181
|
-
|
|
182
|
-
this.getReactApplicationContext(),
|
|
183
|
-
options -> getSentryAndroidOptions(options, rnOptions, logger));
|
|
165
|
+
RNSentryStart.startWithOptions(
|
|
166
|
+
this.getReactApplicationContext(), rnOptions, getCurrentActivity(), logger);
|
|
184
167
|
|
|
185
168
|
promise.resolve(true);
|
|
186
169
|
}
|
|
187
170
|
|
|
188
|
-
protected void getSentryAndroidOptions(
|
|
189
|
-
@NotNull SentryAndroidOptions options, @NotNull ReadableMap rnOptions, ILogger logger) {
|
|
190
|
-
@Nullable SdkVersion sdkVersion = options.getSdkVersion();
|
|
191
|
-
if (sdkVersion == null) {
|
|
192
|
-
sdkVersion = new SdkVersion(RNSentryVersion.ANDROID_SDK_NAME, BuildConfig.VERSION_NAME);
|
|
193
|
-
} else {
|
|
194
|
-
sdkVersion.setName(RNSentryVersion.ANDROID_SDK_NAME);
|
|
195
|
-
}
|
|
196
|
-
sdkVersion.addPackage(
|
|
197
|
-
RNSentryVersion.REACT_NATIVE_SDK_PACKAGE_NAME,
|
|
198
|
-
RNSentryVersion.REACT_NATIVE_SDK_PACKAGE_VERSION);
|
|
199
|
-
|
|
200
|
-
options.setSentryClientName(sdkVersion.getName() + "/" + sdkVersion.getVersion());
|
|
201
|
-
options.setNativeSdkName(RNSentryVersion.NATIVE_SDK_NAME);
|
|
202
|
-
options.setSdkVersion(sdkVersion);
|
|
203
|
-
|
|
204
|
-
if (rnOptions.hasKey("debug") && rnOptions.getBoolean("debug")) {
|
|
205
|
-
options.setDebug(true);
|
|
206
|
-
}
|
|
207
|
-
if (rnOptions.hasKey("dsn") && rnOptions.getString("dsn") != null) {
|
|
208
|
-
String dsn = rnOptions.getString("dsn");
|
|
209
|
-
logger.log(SentryLevel.INFO, String.format("Starting with DSN: '%s'", dsn));
|
|
210
|
-
options.setDsn(dsn);
|
|
211
|
-
} else {
|
|
212
|
-
// SentryAndroid needs an empty string fallback for the dsn.
|
|
213
|
-
options.setDsn("");
|
|
214
|
-
}
|
|
215
|
-
if (rnOptions.hasKey("sampleRate")) {
|
|
216
|
-
options.setSampleRate(rnOptions.getDouble("sampleRate"));
|
|
217
|
-
}
|
|
218
|
-
if (rnOptions.hasKey("sendClientReports")) {
|
|
219
|
-
options.setSendClientReports(rnOptions.getBoolean("sendClientReports"));
|
|
220
|
-
}
|
|
221
|
-
if (rnOptions.hasKey("maxBreadcrumbs")) {
|
|
222
|
-
options.setMaxBreadcrumbs(rnOptions.getInt("maxBreadcrumbs"));
|
|
223
|
-
}
|
|
224
|
-
if (rnOptions.hasKey("maxCacheItems")) {
|
|
225
|
-
options.setMaxCacheItems(rnOptions.getInt("maxCacheItems"));
|
|
226
|
-
}
|
|
227
|
-
if (rnOptions.hasKey("environment") && rnOptions.getString("environment") != null) {
|
|
228
|
-
options.setEnvironment(rnOptions.getString("environment"));
|
|
229
|
-
}
|
|
230
|
-
if (rnOptions.hasKey("release") && rnOptions.getString("release") != null) {
|
|
231
|
-
options.setRelease(rnOptions.getString("release"));
|
|
232
|
-
}
|
|
233
|
-
if (rnOptions.hasKey("dist") && rnOptions.getString("dist") != null) {
|
|
234
|
-
options.setDist(rnOptions.getString("dist"));
|
|
235
|
-
}
|
|
236
|
-
if (rnOptions.hasKey("enableAutoSessionTracking")) {
|
|
237
|
-
options.setEnableAutoSessionTracking(rnOptions.getBoolean("enableAutoSessionTracking"));
|
|
238
|
-
}
|
|
239
|
-
if (rnOptions.hasKey("sessionTrackingIntervalMillis")) {
|
|
240
|
-
options.setSessionTrackingIntervalMillis(rnOptions.getInt("sessionTrackingIntervalMillis"));
|
|
241
|
-
}
|
|
242
|
-
if (rnOptions.hasKey("shutdownTimeout")) {
|
|
243
|
-
options.setShutdownTimeoutMillis(rnOptions.getInt("shutdownTimeout"));
|
|
244
|
-
}
|
|
245
|
-
if (rnOptions.hasKey("enableNdkScopeSync")) {
|
|
246
|
-
options.setEnableScopeSync(rnOptions.getBoolean("enableNdkScopeSync"));
|
|
247
|
-
}
|
|
248
|
-
if (rnOptions.hasKey("attachStacktrace")) {
|
|
249
|
-
options.setAttachStacktrace(rnOptions.getBoolean("attachStacktrace"));
|
|
250
|
-
}
|
|
251
|
-
if (rnOptions.hasKey("attachThreads")) {
|
|
252
|
-
// JS use top level stacktrace and android attaches Threads which hides them so
|
|
253
|
-
// by default we hide.
|
|
254
|
-
options.setAttachThreads(rnOptions.getBoolean("attachThreads"));
|
|
255
|
-
}
|
|
256
|
-
if (rnOptions.hasKey("attachScreenshot")) {
|
|
257
|
-
options.setAttachScreenshot(rnOptions.getBoolean("attachScreenshot"));
|
|
258
|
-
}
|
|
259
|
-
if (rnOptions.hasKey("attachViewHierarchy")) {
|
|
260
|
-
options.setAttachViewHierarchy(rnOptions.getBoolean("attachViewHierarchy"));
|
|
261
|
-
}
|
|
262
|
-
if (rnOptions.hasKey("sendDefaultPii")) {
|
|
263
|
-
options.setSendDefaultPii(rnOptions.getBoolean("sendDefaultPii"));
|
|
264
|
-
}
|
|
265
|
-
if (rnOptions.hasKey("maxQueueSize")) {
|
|
266
|
-
options.setMaxQueueSize(rnOptions.getInt("maxQueueSize"));
|
|
267
|
-
}
|
|
268
|
-
if (rnOptions.hasKey("enableNdk")) {
|
|
269
|
-
options.setEnableNdk(rnOptions.getBoolean("enableNdk"));
|
|
270
|
-
}
|
|
271
|
-
if (rnOptions.hasKey("spotlight")) {
|
|
272
|
-
if (rnOptions.getType("spotlight") == ReadableType.Boolean) {
|
|
273
|
-
options.setEnableSpotlight(rnOptions.getBoolean("spotlight"));
|
|
274
|
-
options.setSpotlightConnectionUrl(rnOptions.getString("defaultSidecarUrl"));
|
|
275
|
-
} else if (rnOptions.getType("spotlight") == ReadableType.String) {
|
|
276
|
-
options.setEnableSpotlight(true);
|
|
277
|
-
options.setSpotlightConnectionUrl(rnOptions.getString("spotlight"));
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
SentryReplayOptions replayOptions = getReplayOptions(rnOptions);
|
|
282
|
-
options.setSessionReplay(replayOptions);
|
|
283
|
-
if (isReplayEnabled(replayOptions)) {
|
|
284
|
-
options.getReplayController().setBreadcrumbConverter(new RNSentryReplayBreadcrumbConverter());
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Exclude Dev Server and Sentry Dsn request from Breadcrumbs
|
|
288
|
-
String dsn = getURLFromDSN(rnOptions.getString("dsn"));
|
|
289
|
-
String devServerUrl = rnOptions.getString("devServerUrl");
|
|
290
|
-
options.setBeforeBreadcrumb(
|
|
291
|
-
(breadcrumb, hint) -> {
|
|
292
|
-
Object urlObject = breadcrumb.getData("url");
|
|
293
|
-
String url = urlObject instanceof String ? (String) urlObject : "";
|
|
294
|
-
if ("http".equals(breadcrumb.getType())
|
|
295
|
-
&& ((dsn != null && url.startsWith(dsn))
|
|
296
|
-
|| (devServerUrl != null && url.startsWith(devServerUrl)))) {
|
|
297
|
-
return null;
|
|
298
|
-
}
|
|
299
|
-
return breadcrumb;
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
// React native internally throws a JavascriptException.
|
|
303
|
-
// we want to ignore it on the native side to avoid sending it twice.
|
|
304
|
-
options.addIgnoredExceptionForType(JavascriptException.class);
|
|
305
|
-
|
|
306
|
-
options.setBeforeSend(
|
|
307
|
-
(event, hint) -> {
|
|
308
|
-
setEventOriginTag(event);
|
|
309
|
-
addPackages(event, options.getSdkVersion());
|
|
310
|
-
|
|
311
|
-
return event;
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
if (rnOptions.hasKey("enableNativeCrashHandling")
|
|
315
|
-
&& !rnOptions.getBoolean("enableNativeCrashHandling")) {
|
|
316
|
-
final List<Integration> integrations = options.getIntegrations();
|
|
317
|
-
for (final Integration integration : integrations) {
|
|
318
|
-
if (integration instanceof UncaughtExceptionHandlerIntegration
|
|
319
|
-
|| integration instanceof AnrIntegration
|
|
320
|
-
|| integration instanceof NdkIntegration) {
|
|
321
|
-
integrations.remove(integration);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
logger.log(
|
|
326
|
-
SentryLevel.INFO, String.format("Native Integrations '%s'", options.getIntegrations()));
|
|
327
|
-
|
|
328
|
-
final CurrentActivityHolder currentActivityHolder = CurrentActivityHolder.getInstance();
|
|
329
|
-
final Activity currentActivity = getCurrentActivity();
|
|
330
|
-
if (currentActivity != null) {
|
|
331
|
-
currentActivityHolder.setActivity(currentActivity);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
private boolean isReplayEnabled(SentryReplayOptions replayOptions) {
|
|
336
|
-
return replayOptions.getSessionSampleRate() != null
|
|
337
|
-
|| replayOptions.getOnErrorSampleRate() != null;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
private SentryReplayOptions getReplayOptions(@NotNull ReadableMap rnOptions) {
|
|
341
|
-
final SdkVersion replaySdkVersion =
|
|
342
|
-
new SdkVersion(
|
|
343
|
-
RNSentryVersion.REACT_NATIVE_SDK_NAME,
|
|
344
|
-
RNSentryVersion.REACT_NATIVE_SDK_PACKAGE_VERSION);
|
|
345
|
-
@NotNull
|
|
346
|
-
final SentryReplayOptions androidReplayOptions =
|
|
347
|
-
new SentryReplayOptions(false, replaySdkVersion);
|
|
348
|
-
|
|
349
|
-
if (!(rnOptions.hasKey("replaysSessionSampleRate")
|
|
350
|
-
|| rnOptions.hasKey("replaysOnErrorSampleRate"))) {
|
|
351
|
-
return androidReplayOptions;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
androidReplayOptions.setSessionSampleRate(
|
|
355
|
-
rnOptions.hasKey("replaysSessionSampleRate")
|
|
356
|
-
? rnOptions.getDouble("replaysSessionSampleRate")
|
|
357
|
-
: null);
|
|
358
|
-
androidReplayOptions.setOnErrorSampleRate(
|
|
359
|
-
rnOptions.hasKey("replaysOnErrorSampleRate")
|
|
360
|
-
? rnOptions.getDouble("replaysOnErrorSampleRate")
|
|
361
|
-
: null);
|
|
362
|
-
|
|
363
|
-
if (!rnOptions.hasKey("mobileReplayOptions")) {
|
|
364
|
-
return androidReplayOptions;
|
|
365
|
-
}
|
|
366
|
-
@Nullable final ReadableMap rnMobileReplayOptions = rnOptions.getMap("mobileReplayOptions");
|
|
367
|
-
if (rnMobileReplayOptions == null) {
|
|
368
|
-
return androidReplayOptions;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
androidReplayOptions.setMaskAllText(
|
|
372
|
-
!rnMobileReplayOptions.hasKey("maskAllText")
|
|
373
|
-
|| rnMobileReplayOptions.getBoolean("maskAllText"));
|
|
374
|
-
androidReplayOptions.setMaskAllImages(
|
|
375
|
-
!rnMobileReplayOptions.hasKey("maskAllImages")
|
|
376
|
-
|| rnMobileReplayOptions.getBoolean("maskAllImages"));
|
|
377
|
-
|
|
378
|
-
final boolean redactVectors =
|
|
379
|
-
!rnMobileReplayOptions.hasKey("maskAllVectors")
|
|
380
|
-
|| rnMobileReplayOptions.getBoolean("maskAllVectors");
|
|
381
|
-
if (redactVectors) {
|
|
382
|
-
androidReplayOptions.addMaskViewClass("com.horcrux.svg.SvgView"); // react-native-svg
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
androidReplayOptions.setMaskViewContainerClass(RNSentryReplayMask.class.getName());
|
|
386
|
-
androidReplayOptions.setUnmaskViewContainerClass(RNSentryReplayUnmask.class.getName());
|
|
387
|
-
|
|
388
|
-
return androidReplayOptions;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
171
|
public void crash() {
|
|
392
172
|
throw new RuntimeException("TEST - Sentry Client Crash (only works in release mode)");
|
|
393
173
|
}
|
|
@@ -974,51 +754,6 @@ public class RNSentryModuleImpl {
|
|
|
974
754
|
promise.resolve(Sentry.isCrashedLastRun());
|
|
975
755
|
}
|
|
976
756
|
|
|
977
|
-
private void setEventOriginTag(SentryEvent event) {
|
|
978
|
-
// We hardcode native-java as only java events are processed by the Android SDK.
|
|
979
|
-
SdkVersion sdk = event.getSdk();
|
|
980
|
-
if (sdk != null) {
|
|
981
|
-
switch (sdk.getName()) {
|
|
982
|
-
case RNSentryVersion.NATIVE_SDK_NAME:
|
|
983
|
-
setEventEnvironmentTag(event, "native");
|
|
984
|
-
break;
|
|
985
|
-
case RNSentryVersion.ANDROID_SDK_NAME:
|
|
986
|
-
setEventEnvironmentTag(event, "java");
|
|
987
|
-
break;
|
|
988
|
-
default:
|
|
989
|
-
break;
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
private void setEventEnvironmentTag(SentryEvent event, String environment) {
|
|
995
|
-
event.setTag("event.origin", "android");
|
|
996
|
-
event.setTag("event.environment", environment);
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
private void addPackages(SentryEvent event, SdkVersion sdk) {
|
|
1000
|
-
SdkVersion eventSdk = event.getSdk();
|
|
1001
|
-
if (eventSdk != null
|
|
1002
|
-
&& "sentry.javascript.react-native".equals(eventSdk.getName())
|
|
1003
|
-
&& sdk != null) {
|
|
1004
|
-
List<SentryPackage> sentryPackages = sdk.getPackages();
|
|
1005
|
-
if (sentryPackages != null) {
|
|
1006
|
-
for (SentryPackage sentryPackage : sentryPackages) {
|
|
1007
|
-
eventSdk.addPackage(sentryPackage.getName(), sentryPackage.getVersion());
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
List<String> integrations = sdk.getIntegrations();
|
|
1012
|
-
if (integrations != null) {
|
|
1013
|
-
for (String integration : integrations) {
|
|
1014
|
-
eventSdk.addIntegration(integration);
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
event.setSdk(eventSdk);
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
757
|
private boolean checkAndroidXAvailability() {
|
|
1023
758
|
try {
|
|
1024
759
|
Class.forName("androidx.core.app.FrameMetricsAggregator");
|
|
@@ -1032,17 +767,4 @@ public class RNSentryModuleImpl {
|
|
|
1032
767
|
private boolean isFrameMetricsAggregatorAvailable() {
|
|
1033
768
|
return androidXAvailable && frameMetricsAggregator != null;
|
|
1034
769
|
}
|
|
1035
|
-
|
|
1036
|
-
public static @Nullable String getURLFromDSN(@Nullable String dsn) {
|
|
1037
|
-
if (dsn == null) {
|
|
1038
|
-
return null;
|
|
1039
|
-
}
|
|
1040
|
-
URI uri = null;
|
|
1041
|
-
try {
|
|
1042
|
-
uri = new URI(dsn);
|
|
1043
|
-
} catch (URISyntaxException e) {
|
|
1044
|
-
return null;
|
|
1045
|
-
}
|
|
1046
|
-
return uri.getScheme() + "://" + uri.getHost();
|
|
1047
|
-
}
|
|
1048
770
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
package io.sentry.react;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
5
|
+
import io.sentry.ILogger;
|
|
6
|
+
import io.sentry.Sentry;
|
|
7
|
+
import io.sentry.SentryLevel;
|
|
8
|
+
import io.sentry.android.core.AndroidLogger;
|
|
9
|
+
import io.sentry.android.core.SentryAndroidOptions;
|
|
10
|
+
import org.jetbrains.annotations.NotNull;
|
|
11
|
+
import org.json.JSONObject;
|
|
12
|
+
|
|
13
|
+
public final class RNSentrySDK {
|
|
14
|
+
private static final String CONFIGURATION_FILE = "sentry.options.json";
|
|
15
|
+
private static final String NAME = "RNSentrySDK";
|
|
16
|
+
|
|
17
|
+
private static final ILogger logger = new AndroidLogger(NAME);
|
|
18
|
+
|
|
19
|
+
private RNSentrySDK() {
|
|
20
|
+
throw new AssertionError("Utility class should not be instantiated");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static void init(
|
|
24
|
+
@NotNull final Context context,
|
|
25
|
+
@NotNull Sentry.OptionsConfiguration<SentryAndroidOptions> configuration,
|
|
26
|
+
@NotNull String configurationFile,
|
|
27
|
+
@NotNull ILogger logger) {
|
|
28
|
+
try {
|
|
29
|
+
JSONObject jsonObject =
|
|
30
|
+
RNSentryJsonUtils.getOptionsFromConfigurationFile(context, configurationFile, logger);
|
|
31
|
+
if (jsonObject == null) {
|
|
32
|
+
RNSentryStart.startWithConfiguration(context, configuration);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
ReadableMap rnOptions = RNSentryJsonConverter.convertToWritable(jsonObject);
|
|
36
|
+
if (rnOptions == null) {
|
|
37
|
+
RNSentryStart.startWithConfiguration(context, configuration);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
RNSentryStart.startWithOptions(context, rnOptions, configuration, logger);
|
|
41
|
+
} catch (Exception e) {
|
|
42
|
+
logger.log(
|
|
43
|
+
SentryLevel.ERROR, "Failed to start Sentry with options from configuration file.", e);
|
|
44
|
+
throw new RuntimeException("Failed to initialize Sentry's React Native SDK", e);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @experimental Start the Native Android SDK with the provided configuration options. Uses as a
|
|
50
|
+
* base configurations the `sentry.options.json` configuration file if it exists.
|
|
51
|
+
* @param context Android Context
|
|
52
|
+
* @param configuration configuration options
|
|
53
|
+
*/
|
|
54
|
+
public static void init(
|
|
55
|
+
@NotNull final Context context,
|
|
56
|
+
@NotNull Sentry.OptionsConfiguration<SentryAndroidOptions> configuration) {
|
|
57
|
+
init(context, configuration, CONFIGURATION_FILE, logger);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @experimental Start the Native Android SDK with options from `sentry.options.json`
|
|
62
|
+
* configuration file.
|
|
63
|
+
* @param context Android Context
|
|
64
|
+
*/
|
|
65
|
+
public static void init(@NotNull final Context context) {
|
|
66
|
+
init(context, options -> {}, CONFIGURATION_FILE, logger);
|
|
67
|
+
}
|
|
68
|
+
}
|