@sentry/react-native 6.1.0 → 6.3.0-beta.1
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 +6 -0
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +183 -127
- 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 +7 -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/debugsymbolicator.js +4 -37
- package/dist/js/integrations/debugsymbolicator.js.map +1 -1
- package/dist/js/integrations/debugsymbolicatorutils.d.ts +6 -2
- package/dist/js/integrations/debugsymbolicatorutils.d.ts.map +1 -1
- package/dist/js/integrations/debugsymbolicatorutils.js +44 -27
- package/dist/js/integrations/debugsymbolicatorutils.js.map +1 -1
- package/dist/js/integrations/default.d.ts.map +1 -1
- package/dist/js/integrations/default.js +11 -7
- package/dist/js/integrations/default.js.map +1 -1
- package/dist/js/integrations/devicecontext.d.ts.map +1 -1
- package/dist/js/integrations/devicecontext.js +7 -3
- package/dist/js/integrations/devicecontext.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/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +40 -2
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tools/metroMiddleware.d.ts +15 -0
- package/dist/js/tools/metroMiddleware.d.ts.map +1 -0
- package/dist/js/tools/metroMiddleware.js +105 -0
- package/dist/js/tools/metroMiddleware.js.map +1 -0
- package/dist/js/tools/metroconfig.d.ts +7 -1
- package/dist/js/tools/metroconfig.d.ts.map +1 -1
- package/dist/js/tools/metroconfig.js +9 -1
- package/dist/js/tools/metroconfig.js.map +1 -1
- package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
- package/dist/js/tracing/reactnativetracing.js +17 -1
- package/dist/js/tracing/reactnativetracing.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.d.ts.map +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts +4 -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 +417 -303
- package/ios/RNSentryBreadcrumb.h +2 -2
- package/ios/RNSentryBreadcrumb.m +13 -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 +17 -16
- package/scripts/expo-upload-sourcemaps.js +16 -0
- package/scripts/sentry-xcode-debug-files.sh +6 -0
- package/scripts/sentry-xcode.sh +4 -0
- package/sentry.gradle +13 -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/debugsymbolicatorutils.d.ts +6 -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 +4 -0
package/ios/RNSentry.mm
CHANGED
|
@@ -1,53 +1,56 @@
|
|
|
1
|
-
#import <dlfcn.h>
|
|
2
1
|
#import "RNSentry.h"
|
|
2
|
+
#import "RNSentryTimeToDisplay.h"
|
|
3
|
+
#import <dlfcn.h>
|
|
3
4
|
|
|
4
5
|
#if __has_include(<React/RCTConvert.h>)
|
|
5
|
-
#import <React/RCTConvert.h>
|
|
6
|
+
# import <React/RCTConvert.h>
|
|
6
7
|
#else
|
|
7
|
-
#import "RCTConvert.h"
|
|
8
|
+
# import "RCTConvert.h"
|
|
8
9
|
#endif
|
|
9
10
|
|
|
10
11
|
#if __has_include(<hermes/hermes.h>) && SENTRY_PROFILING_SUPPORTED
|
|
11
|
-
#define SENTRY_PROFILING_ENABLED 1
|
|
12
|
-
#import <Sentry/SentryProfilingConditionals.h>
|
|
12
|
+
# define SENTRY_PROFILING_ENABLED 1
|
|
13
|
+
# import <Sentry/SentryProfilingConditionals.h>
|
|
13
14
|
#else
|
|
14
|
-
#define SENTRY_PROFILING_ENABLED 0
|
|
15
|
-
#define SENTRY_TARGET_PROFILING_SUPPORTED 0
|
|
15
|
+
# define SENTRY_PROFILING_ENABLED 0
|
|
16
|
+
# define SENTRY_TARGET_PROFILING_SUPPORTED 0
|
|
16
17
|
#endif
|
|
17
18
|
|
|
19
|
+
#import "RNSentryBreadcrumb.h"
|
|
20
|
+
#import "RNSentryId.h"
|
|
18
21
|
#import <Sentry/PrivateSentrySDKOnly.h>
|
|
19
|
-
#import <Sentry/
|
|
20
|
-
#import <Sentry/SentryOptions+HybridSDKs.h>
|
|
22
|
+
#import <Sentry/SentryAppStartMeasurement.h>
|
|
21
23
|
#import <Sentry/SentryBinaryImageCache.h>
|
|
24
|
+
#import <Sentry/SentryDebugImageProvider+HybridSDKs.h>
|
|
22
25
|
#import <Sentry/SentryDependencyContainer.h>
|
|
23
26
|
#import <Sentry/SentryFormatter.h>
|
|
24
|
-
#import <Sentry/
|
|
25
|
-
#import
|
|
26
|
-
#import "RNSentryBreadcrumb.h"
|
|
27
|
+
#import <Sentry/SentryOptions+HybridSDKs.h>
|
|
28
|
+
#import <Sentry/SentryScreenFrames.h>
|
|
27
29
|
|
|
28
30
|
// This guard prevents importing Hermes in JSC apps
|
|
29
31
|
#if SENTRY_PROFILING_ENABLED
|
|
30
|
-
#import <hermes/hermes.h>
|
|
32
|
+
# import <hermes/hermes.h>
|
|
31
33
|
#endif
|
|
32
34
|
|
|
33
35
|
// Thanks to this guard, we won't import this header when we build for the old architecture.
|
|
34
36
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
35
|
-
#import "RNSentrySpec.h"
|
|
37
|
+
# import "RNSentrySpec.h"
|
|
36
38
|
#endif
|
|
37
39
|
|
|
38
|
-
#import "RNSentryEvents.h"
|
|
39
40
|
#import "RNSentryDependencyContainer.h"
|
|
41
|
+
#import "RNSentryEvents.h"
|
|
40
42
|
|
|
41
43
|
#if SENTRY_TARGET_REPLAY_SUPPORTED
|
|
42
|
-
#import "RNSentryReplay.h"
|
|
44
|
+
# import "RNSentryReplay.h"
|
|
43
45
|
#endif
|
|
44
46
|
|
|
45
47
|
#if SENTRY_HAS_UIKIT
|
|
46
|
-
#import "
|
|
47
|
-
#import "
|
|
48
|
+
# import "RNSentryFramesTrackerListener.h"
|
|
49
|
+
# import "RNSentryRNSScreen.h"
|
|
48
50
|
#endif
|
|
49
51
|
|
|
50
|
-
@interface
|
|
52
|
+
@interface
|
|
53
|
+
SentrySDK (RNSentry)
|
|
51
54
|
|
|
52
55
|
+ (void)captureEnvelope:(SentryEnvelope *)envelope;
|
|
53
56
|
|
|
@@ -57,11 +60,12 @@
|
|
|
57
60
|
|
|
58
61
|
static bool hasFetchedAppStart;
|
|
59
62
|
|
|
60
|
-
static NSString*
|
|
63
|
+
static NSString *const nativeSdkName = @"sentry.cocoa.react-native";
|
|
61
64
|
|
|
62
65
|
@implementation RNSentry {
|
|
63
66
|
bool sentHybridSdkDidBecomeActive;
|
|
64
67
|
bool hasListeners;
|
|
68
|
+
RNSentryTimeToDisplay *_timeToDisplay;
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
- (dispatch_queue_t)methodQueue
|
|
@@ -69,39 +73,44 @@ static NSString* const nativeSdkName = @"sentry.cocoa.react-native";
|
|
|
69
73
|
return dispatch_get_main_queue();
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
+ (BOOL)requiresMainQueueSetup
|
|
76
|
+
+ (BOOL)requiresMainQueueSetup
|
|
77
|
+
{
|
|
73
78
|
return YES;
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
RCT_EXPORT_MODULE()
|
|
77
82
|
|
|
78
|
-
RCT_EXPORT_METHOD(initNativeSdk
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
RCT_EXPORT_METHOD(initNativeSdk
|
|
84
|
+
: (NSDictionary *_Nonnull)options resolve
|
|
85
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
86
|
+
: (RCTPromiseRejectBlock)reject)
|
|
81
87
|
{
|
|
82
88
|
NSError *error = nil;
|
|
83
|
-
SentryOptions*
|
|
89
|
+
SentryOptions *sentryOptions = [self createOptionsWithDictionary:options error:&error];
|
|
84
90
|
if (error != nil) {
|
|
85
91
|
reject(@"SentryReactNative", error.localizedDescription, error);
|
|
86
92
|
return;
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
NSString *sdkVersion = [PrivateSentrySDKOnly getSdkVersionString];
|
|
90
|
-
[PrivateSentrySDKOnly setSdkName:
|
|
96
|
+
[PrivateSentrySDKOnly setSdkName:nativeSdkName andVersionString:sdkVersion];
|
|
91
97
|
|
|
92
98
|
[SentrySDK startWithOptions:sentryOptions];
|
|
93
99
|
|
|
94
100
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
95
|
-
BOOL appIsActive =
|
|
101
|
+
BOOL appIsActive =
|
|
102
|
+
[[UIApplication sharedApplication] applicationState] == UIApplicationStateActive;
|
|
96
103
|
#else
|
|
97
104
|
BOOL appIsActive = [[NSApplication sharedApplication] isActive];
|
|
98
105
|
#endif
|
|
99
106
|
|
|
100
|
-
// If the app is active/in foreground, and we have not sent the SentryHybridSdkDidBecomeActive
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
// If the app is active/in foreground, and we have not sent the SentryHybridSdkDidBecomeActive
|
|
108
|
+
// notification, send it.
|
|
109
|
+
if (appIsActive && !sentHybridSdkDidBecomeActive
|
|
110
|
+
&& (PrivateSentrySDKOnly.options.enableAutoSessionTracking
|
|
111
|
+
|| PrivateSentrySDKOnly.options.enableWatchdogTerminationTracking)) {
|
|
112
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:@"SentryHybridSdkDidBecomeActive"
|
|
113
|
+
object:nil];
|
|
105
114
|
|
|
106
115
|
sentHybridSdkDidBecomeActive = true;
|
|
107
116
|
}
|
|
@@ -114,13 +123,15 @@ RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options
|
|
|
114
123
|
}
|
|
115
124
|
|
|
116
125
|
- (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options
|
|
117
|
-
|
|
126
|
+
error:(NSError *_Nonnull *_Nonnull)errorPointer
|
|
118
127
|
{
|
|
119
|
-
SentryBeforeSendEventCallback beforeSend = ^SentryEvent*(SentryEvent *event)
|
|
120
|
-
|
|
121
|
-
//
|
|
128
|
+
SentryBeforeSendEventCallback beforeSend = ^SentryEvent *(SentryEvent *event)
|
|
129
|
+
{
|
|
130
|
+
// We don't want to send an event after startup that came from a Unhandled JS Exception of
|
|
131
|
+
// react native Because we sent it already before the app crashed.
|
|
122
132
|
if (nil != event.exceptions.firstObject.type &&
|
|
123
|
-
[event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location
|
|
133
|
+
[event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location
|
|
134
|
+
!= NSNotFound) {
|
|
124
135
|
return nil;
|
|
125
136
|
}
|
|
126
137
|
|
|
@@ -129,25 +140,44 @@ RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options
|
|
|
129
140
|
return event;
|
|
130
141
|
};
|
|
131
142
|
|
|
132
|
-
NSMutableDictionary *
|
|
143
|
+
NSMutableDictionary *mutableOptions = [options mutableCopy];
|
|
133
144
|
[mutableOptions setValue:beforeSend forKey:@"beforeSend"];
|
|
134
145
|
|
|
135
|
-
// remove performance traces sample rate and traces sampler since we don't want to synchronize
|
|
136
|
-
// to the Native SDKs.
|
|
137
|
-
//
|
|
146
|
+
// remove performance traces sample rate and traces sampler since we don't want to synchronize
|
|
147
|
+
// these configurations to the Native SDKs. The user could tho initialize the SDK manually and
|
|
148
|
+
// set themselves.
|
|
138
149
|
[mutableOptions removeObjectForKey:@"tracesSampleRate"];
|
|
139
150
|
[mutableOptions removeObjectForKey:@"tracesSampler"];
|
|
140
151
|
[mutableOptions removeObjectForKey:@"enableTracing"];
|
|
141
152
|
|
|
153
|
+
_timeToDisplay = [[RNSentryTimeToDisplay alloc] init];
|
|
154
|
+
|
|
142
155
|
#if SENTRY_TARGET_REPLAY_SUPPORTED
|
|
143
156
|
[RNSentryReplay updateOptions:mutableOptions];
|
|
144
157
|
#endif
|
|
145
158
|
|
|
146
|
-
SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:mutableOptions
|
|
159
|
+
SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:mutableOptions
|
|
160
|
+
didFailWithError:errorPointer];
|
|
147
161
|
if (*errorPointer != nil) {
|
|
148
162
|
return nil;
|
|
149
163
|
}
|
|
150
164
|
|
|
165
|
+
// Exclude Dev Server and Sentry Dsn request from Breadcrumbs
|
|
166
|
+
NSString *dsn = [self getURLFromDSN:[mutableOptions valueForKey:@"dsn"]];
|
|
167
|
+
NSString *devServerUrl = [mutableOptions valueForKey:@"devServerUrl"];
|
|
168
|
+
sentryOptions.beforeBreadcrumb
|
|
169
|
+
= ^SentryBreadcrumb *_Nullable(SentryBreadcrumb *_Nonnull breadcrumb)
|
|
170
|
+
{
|
|
171
|
+
NSString *url = breadcrumb.data[@"url"] ?: @"";
|
|
172
|
+
|
|
173
|
+
if ([@"http" isEqualToString:breadcrumb.type]
|
|
174
|
+
&& ((dsn != nil && [url hasPrefix:dsn])
|
|
175
|
+
|| (devServerUrl != nil && [url hasPrefix:devServerUrl]))) {
|
|
176
|
+
return nil;
|
|
177
|
+
}
|
|
178
|
+
return breadcrumb;
|
|
179
|
+
};
|
|
180
|
+
|
|
151
181
|
if ([mutableOptions valueForKey:@"enableNativeCrashHandling"] != nil) {
|
|
152
182
|
BOOL enableNativeCrashHandling = [mutableOptions[@"enableNativeCrashHandling"] boolValue];
|
|
153
183
|
|
|
@@ -158,58 +188,88 @@ RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options
|
|
|
158
188
|
}
|
|
159
189
|
}
|
|
160
190
|
|
|
191
|
+
// Set spotlight option
|
|
192
|
+
if ([mutableOptions valueForKey:@"spotlight"] != nil) {
|
|
193
|
+
id spotlightValue = [mutableOptions valueForKey:@"spotlight"];
|
|
194
|
+
if ([spotlightValue isKindOfClass:[NSString class]]) {
|
|
195
|
+
NSLog(@"Using Spotlight on address: %@", spotlightValue);
|
|
196
|
+
sentryOptions.enableSpotlight = true;
|
|
197
|
+
sentryOptions.spotlightUrl = spotlightValue;
|
|
198
|
+
} else if ([spotlightValue isKindOfClass:[NSNumber class]]) {
|
|
199
|
+
sentryOptions.enableSpotlight = [spotlightValue boolValue];
|
|
200
|
+
id defaultSpotlightUrl = [mutableOptions valueForKey:@"defaultSidecarUrl"];
|
|
201
|
+
if (defaultSpotlightUrl != nil) {
|
|
202
|
+
sentryOptions.spotlightUrl = defaultSpotlightUrl;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
161
207
|
// Enable the App start and Frames tracking measurements
|
|
162
208
|
if ([mutableOptions valueForKey:@"enableAutoPerformanceTracing"] != nil) {
|
|
163
|
-
BOOL enableAutoPerformanceTracing =
|
|
209
|
+
BOOL enableAutoPerformanceTracing =
|
|
210
|
+
[mutableOptions[@"enableAutoPerformanceTracing"] boolValue];
|
|
164
211
|
PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = enableAutoPerformanceTracing;
|
|
165
212
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
166
213
|
PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = enableAutoPerformanceTracing;
|
|
167
214
|
#endif
|
|
168
215
|
}
|
|
169
216
|
|
|
217
|
+
// Failed requests can only be enabled in one SDK to avoid duplicates
|
|
218
|
+
sentryOptions.enableCaptureFailedRequests = @NO;
|
|
219
|
+
|
|
170
220
|
return sentryOptions;
|
|
171
221
|
}
|
|
172
222
|
|
|
173
|
-
- (
|
|
174
|
-
|
|
175
|
-
|
|
223
|
+
- (NSString *_Nullable)getURLFromDSN:(NSString *)dsn
|
|
224
|
+
{
|
|
225
|
+
NSURL *url = [NSURL URLWithString:dsn];
|
|
226
|
+
if (!url) {
|
|
227
|
+
return nil;
|
|
228
|
+
}
|
|
229
|
+
return [NSString stringWithFormat:@"%@://%@", url.scheme, url.host];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
- (void)setEventOriginTag:(SentryEvent *)event
|
|
233
|
+
{
|
|
234
|
+
if (event.sdk != nil) {
|
|
235
|
+
NSString *sdkName = event.sdk[@"name"];
|
|
176
236
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
237
|
+
// If the event is from react native, it gets set
|
|
238
|
+
// there and we do not handle it here.
|
|
239
|
+
if ([sdkName isEqual:nativeSdkName]) {
|
|
240
|
+
[self setEventEnvironmentTag:event origin:@"ios" environment:@"native"];
|
|
241
|
+
}
|
|
181
242
|
}
|
|
182
|
-
}
|
|
183
243
|
}
|
|
184
244
|
|
|
185
245
|
- (void)setEventEnvironmentTag:(SentryEvent *)event
|
|
186
246
|
origin:(NSString *)origin
|
|
187
|
-
environment:(NSString *)environment
|
|
188
|
-
|
|
247
|
+
environment:(NSString *)environment
|
|
248
|
+
{
|
|
249
|
+
NSMutableDictionary *newTags = [NSMutableDictionary new];
|
|
189
250
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
251
|
+
if (nil != event.tags && [event.tags count] > 0) {
|
|
252
|
+
[newTags addEntriesFromDictionary:event.tags];
|
|
253
|
+
}
|
|
254
|
+
if (nil != origin) {
|
|
255
|
+
[newTags setValue:origin forKey:@"event.origin"];
|
|
256
|
+
}
|
|
257
|
+
if (nil != environment) {
|
|
258
|
+
[newTags setValue:environment forKey:@"event.environment"];
|
|
259
|
+
}
|
|
199
260
|
|
|
200
|
-
|
|
261
|
+
event.tags = newTags;
|
|
201
262
|
}
|
|
202
263
|
|
|
203
|
-
RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking
|
|
204
|
-
|
|
264
|
+
RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking
|
|
265
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
266
|
+
: (RCTPromiseRejectBlock)reject)
|
|
205
267
|
{
|
|
206
268
|
#if SENTRY_HAS_UIKIT
|
|
207
269
|
if ([[NSThread currentThread] isMainThread]) {
|
|
208
270
|
[RNSentryRNSScreen swizzleViewDidAppear];
|
|
209
271
|
} else {
|
|
210
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
211
|
-
[RNSentryRNSScreen swizzleViewDidAppear];
|
|
212
|
-
});
|
|
272
|
+
dispatch_async(dispatch_get_main_queue(), ^{ [RNSentryRNSScreen swizzleViewDidAppear]; });
|
|
213
273
|
}
|
|
214
274
|
|
|
215
275
|
[self initFramesTracking];
|
|
@@ -217,48 +277,57 @@ RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking:(RCTPromiseResolveBl
|
|
|
217
277
|
resolve(nil);
|
|
218
278
|
}
|
|
219
279
|
|
|
220
|
-
- (void)initFramesTracking
|
|
280
|
+
- (void)initFramesTracking
|
|
281
|
+
{
|
|
221
282
|
#if SENTRY_HAS_UIKIT
|
|
222
283
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
284
|
+
RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) {
|
|
285
|
+
if (self->hasListeners) {
|
|
286
|
+
[self
|
|
287
|
+
sendEventWithName:RNSentryNewFrameEvent
|
|
288
|
+
body:@{ @"newFrameTimestampInSeconds" : newFrameTimestampInSeconds }];
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
[[RNSentryDependencyContainer sharedInstance]
|
|
292
|
+
initializeFramesTrackerListenerWith:emitNewFrameEvent];
|
|
229
293
|
#endif
|
|
230
294
|
}
|
|
231
295
|
|
|
232
296
|
// Will be called when this module's first listener is added.
|
|
233
|
-
-(void)startObserving
|
|
297
|
+
- (void)startObserving
|
|
298
|
+
{
|
|
234
299
|
hasListeners = YES;
|
|
235
300
|
}
|
|
236
301
|
|
|
237
302
|
// Will be called when this module's last listener is removed, or on dealloc.
|
|
238
|
-
-(void)stopObserving
|
|
303
|
+
- (void)stopObserving
|
|
304
|
+
{
|
|
239
305
|
hasListeners = NO;
|
|
240
306
|
}
|
|
241
307
|
|
|
242
|
-
- (NSArray<NSString *> *)supportedEvents
|
|
243
|
-
|
|
308
|
+
- (NSArray<NSString *> *)supportedEvents
|
|
309
|
+
{
|
|
310
|
+
return @[ RNSentryNewFrameEvent ];
|
|
244
311
|
}
|
|
245
312
|
|
|
246
|
-
RCT_EXPORT_METHOD(fetchNativeSdkInfo
|
|
247
|
-
|
|
313
|
+
RCT_EXPORT_METHOD(fetchNativeSdkInfo
|
|
314
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
315
|
+
: (RCTPromiseRejectBlock)reject)
|
|
248
316
|
{
|
|
249
|
-
resolve(@{
|
|
250
|
-
@"name": PrivateSentrySDKOnly.getSdkName,
|
|
251
|
-
@"version": PrivateSentrySDKOnly.getSdkVersionString
|
|
252
|
-
|
|
317
|
+
resolve(@ {
|
|
318
|
+
@"name" : PrivateSentrySDKOnly.getSdkName,
|
|
319
|
+
@"version" : PrivateSentrySDKOnly.getSdkVersionString
|
|
320
|
+
});
|
|
253
321
|
}
|
|
254
322
|
|
|
255
|
-
RCT_EXPORT_METHOD(fetchModules
|
|
256
|
-
|
|
323
|
+
RCT_EXPORT_METHOD(fetchModules
|
|
324
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
325
|
+
: (RCTPromiseRejectBlock)reject)
|
|
257
326
|
{
|
|
258
327
|
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"modules" ofType:@"json"];
|
|
259
|
-
NSString*
|
|
260
|
-
|
|
261
|
-
|
|
328
|
+
NSString *modulesString = [NSString stringWithContentsOfFile:filePath
|
|
329
|
+
encoding:NSUTF8StringEncoding
|
|
330
|
+
error:nil];
|
|
262
331
|
resolve(modulesString);
|
|
263
332
|
}
|
|
264
333
|
|
|
@@ -268,79 +337,90 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, fetchNativePackageName)
|
|
|
268
337
|
return packageName;
|
|
269
338
|
}
|
|
270
339
|
|
|
271
|
-
- (NSDictionary*)
|
|
272
|
-
symbolicate:
|
|
340
|
+
- (NSDictionary *)fetchNativeStackFramesBy:(NSArray<NSNumber *> *)instructionsAddr
|
|
341
|
+
symbolicate:(SymbolicateCallbackType)symbolicate
|
|
273
342
|
{
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
343
|
+
BOOL shouldSymbolicateLocally = [SentrySDK.options debug];
|
|
344
|
+
NSString *appPackageName = [[NSBundle mainBundle] executablePath];
|
|
345
|
+
|
|
346
|
+
NSMutableSet<NSString *> *_Nonnull imagesAddrToRetrieveDebugMetaImages =
|
|
347
|
+
[[NSMutableSet alloc] init];
|
|
348
|
+
NSMutableArray<NSDictionary<NSString *, id> *> *_Nonnull serializedFrames =
|
|
349
|
+
[[NSMutableArray alloc] init];
|
|
350
|
+
|
|
351
|
+
for (NSNumber *addr in instructionsAddr) {
|
|
352
|
+
SentryBinaryImageInfo *_Nullable image = [[[SentryDependencyContainer sharedInstance]
|
|
353
|
+
binaryImageCache] imageByAddress:[addr unsignedLongLongValue]];
|
|
354
|
+
if (image != nil) {
|
|
355
|
+
NSString *imageAddr = sentry_formatHexAddressUInt64([image address]);
|
|
356
|
+
[imagesAddrToRetrieveDebugMetaImages addObject:imageAddr];
|
|
357
|
+
|
|
358
|
+
NSDictionary<NSString *, id> *_Nonnull nativeFrame = @{
|
|
359
|
+
@"platform" : @"cocoa",
|
|
360
|
+
@"instruction_addr" : sentry_formatHexAddress(addr),
|
|
361
|
+
@"package" : [image name],
|
|
362
|
+
@"image_addr" : imageAddr,
|
|
363
|
+
@"in_app" : [NSNumber numberWithBool:[appPackageName isEqualToString:[image name]]],
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
if (shouldSymbolicateLocally) {
|
|
367
|
+
Dl_info symbolsBuffer;
|
|
368
|
+
bool symbols_succeed = false;
|
|
369
|
+
symbols_succeed
|
|
370
|
+
= symbolicate((void *)[addr unsignedLongLongValue], &symbolsBuffer) != 0;
|
|
371
|
+
if (symbols_succeed) {
|
|
372
|
+
NSMutableDictionary<NSString *, id> *_Nonnull symbolicated
|
|
373
|
+
= nativeFrame.mutableCopy;
|
|
374
|
+
symbolicated[@"symbol_addr"]
|
|
375
|
+
= sentry_formatHexAddressUInt64((uintptr_t)symbolsBuffer.dli_saddr);
|
|
376
|
+
symbolicated[@"function"] = [NSString stringWithCString:symbolsBuffer.dli_sname
|
|
377
|
+
encoding:NSUTF8StringEncoding];
|
|
378
|
+
|
|
379
|
+
nativeFrame = symbolicated;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
302
382
|
|
|
303
|
-
|
|
383
|
+
[serializedFrames addObject:nativeFrame];
|
|
384
|
+
} else {
|
|
385
|
+
[serializedFrames addObject:@{
|
|
386
|
+
@"platform" : @"cocoa",
|
|
387
|
+
@"instruction_addr" : sentry_formatHexAddress(addr),
|
|
388
|
+
}];
|
|
304
389
|
}
|
|
305
|
-
|
|
390
|
+
}
|
|
306
391
|
|
|
307
|
-
|
|
392
|
+
if (shouldSymbolicateLocally) {
|
|
393
|
+
return @{
|
|
394
|
+
@"frames" : serializedFrames,
|
|
395
|
+
};
|
|
308
396
|
} else {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
@"instruction_addr": sentry_formatHexAddress(addr),
|
|
312
|
-
}];
|
|
313
|
-
}
|
|
314
|
-
}
|
|
397
|
+
NSMutableArray<NSDictionary<NSString *, id> *> *_Nonnull serializedDebugMetaImages =
|
|
398
|
+
[[NSMutableArray alloc] init];
|
|
315
399
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
};
|
|
320
|
-
} else {
|
|
321
|
-
NSMutableArray<NSDictionary<NSString *, id> *> * _Nonnull serializedDebugMetaImages = [[NSMutableArray alloc] init];
|
|
400
|
+
NSArray<SentryDebugMeta *> *debugMetaImages =
|
|
401
|
+
[[[SentryDependencyContainer sharedInstance] debugImageProvider]
|
|
402
|
+
getDebugImagesForImageAddressesFromCache:imagesAddrToRetrieveDebugMetaImages];
|
|
322
403
|
|
|
323
|
-
|
|
404
|
+
for (SentryDebugMeta *debugImage in debugMetaImages) {
|
|
405
|
+
[serializedDebugMetaImages addObject:[debugImage serialize]];
|
|
406
|
+
}
|
|
324
407
|
|
|
325
|
-
|
|
326
|
-
|
|
408
|
+
return @{
|
|
409
|
+
@"frames" : serializedFrames,
|
|
410
|
+
@"debugMetaImages" : serializedDebugMetaImages,
|
|
411
|
+
};
|
|
327
412
|
}
|
|
328
|
-
|
|
329
|
-
return @{
|
|
330
|
-
@"frames": serializedFrames,
|
|
331
|
-
@"debugMetaImages": serializedDebugMetaImages,
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
413
|
}
|
|
335
414
|
|
|
336
|
-
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy
|
|
415
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy
|
|
416
|
+
: (NSArray *)instructionsAddr)
|
|
337
417
|
{
|
|
338
|
-
|
|
339
|
-
symbolicate:dladdr];
|
|
418
|
+
return [self fetchNativeStackFramesBy:instructionsAddr symbolicate:dladdr];
|
|
340
419
|
}
|
|
341
420
|
|
|
342
|
-
RCT_EXPORT_METHOD(fetchNativeDeviceContexts
|
|
343
|
-
|
|
421
|
+
RCT_EXPORT_METHOD(fetchNativeDeviceContexts
|
|
422
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
423
|
+
: (RCTPromiseRejectBlock)reject)
|
|
344
424
|
{
|
|
345
425
|
if (PrivateSentrySDKOnly.options.debug) {
|
|
346
426
|
NSLog(@"Bridge call to: deviceContexts");
|
|
@@ -348,55 +428,74 @@ RCT_EXPORT_METHOD(fetchNativeDeviceContexts:(RCTPromiseResolveBlock)resolve
|
|
|
348
428
|
__block NSMutableDictionary<NSString *, id> *serializedScope;
|
|
349
429
|
// Temp work around until sorted out this API in sentry-cocoa.
|
|
350
430
|
// TODO: If the callback isnt' executed the promise wouldn't be resolved.
|
|
351
|
-
[SentrySDK configureScope:^(SentryScope *
|
|
431
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
|
|
352
432
|
serializedScope = [[scope serialize] mutableCopy];
|
|
353
433
|
|
|
354
|
-
NSDictionary<NSString *, id>
|
|
434
|
+
NSDictionary<NSString *, id> *user = [serializedScope valueForKey:@"user"];
|
|
355
435
|
if (user == nil) {
|
|
356
|
-
[serializedScope
|
|
357
|
-
|
|
358
|
-
forKey:@"user"];
|
|
436
|
+
[serializedScope setValue:@ { @"id" : PrivateSentrySDKOnly.installationID }
|
|
437
|
+
forKey:@"user"];
|
|
359
438
|
}
|
|
360
439
|
|
|
361
440
|
if (PrivateSentrySDKOnly.options.debug) {
|
|
362
|
-
NSData *data = [NSJSONSerialization dataWithJSONObject:serializedScope
|
|
363
|
-
|
|
441
|
+
NSData *data = [NSJSONSerialization dataWithJSONObject:serializedScope
|
|
442
|
+
options:0
|
|
443
|
+
error:nil];
|
|
444
|
+
NSString *debugContext = [[NSString alloc] initWithData:data
|
|
445
|
+
encoding:NSUTF8StringEncoding];
|
|
364
446
|
NSLog(@"Contexts: %@", debugContext);
|
|
365
447
|
}
|
|
366
448
|
}];
|
|
367
449
|
|
|
368
450
|
NSDictionary<NSString *, id> *extraContext = [PrivateSentrySDKOnly getExtraContext];
|
|
369
|
-
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *contexts =
|
|
451
|
+
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *contexts =
|
|
452
|
+
[serializedScope[@"context"] mutableCopy];
|
|
370
453
|
|
|
371
454
|
if (extraContext && [extraContext[@"device"] isKindOfClass:[NSDictionary class]]) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
455
|
+
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *deviceContext =
|
|
456
|
+
[contexts[@"device"] mutableCopy];
|
|
457
|
+
[deviceContext addEntriesFromDictionary:extraContext[@"device"]];
|
|
458
|
+
[contexts setValue:deviceContext forKey:@"device"];
|
|
375
459
|
}
|
|
376
460
|
|
|
377
461
|
if (extraContext && [extraContext[@"app"] isKindOfClass:[NSDictionary class]]) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
462
|
+
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *appContext =
|
|
463
|
+
[contexts[@"app"] mutableCopy];
|
|
464
|
+
[appContext addEntriesFromDictionary:extraContext[@"app"]];
|
|
465
|
+
[contexts setValue:appContext forKey:@"app"];
|
|
381
466
|
}
|
|
382
467
|
|
|
383
468
|
[serializedScope setValue:contexts forKey:@"contexts"];
|
|
384
469
|
[serializedScope removeObjectForKey:@"context"];
|
|
470
|
+
|
|
471
|
+
// Remove react-native breadcrumbs
|
|
472
|
+
NSPredicate *removeRNBreadcrumbsPredicate =
|
|
473
|
+
[NSPredicate predicateWithBlock:^BOOL(NSDictionary *breadcrumb, NSDictionary *bindings) {
|
|
474
|
+
return ![breadcrumb[@"origin"] isEqualToString:@"react-native"];
|
|
475
|
+
}];
|
|
476
|
+
NSArray *breadcrumbs = [[serializedScope[@"breadcrumbs"] mutableCopy]
|
|
477
|
+
filteredArrayUsingPredicate:removeRNBreadcrumbsPredicate];
|
|
478
|
+
[serializedScope setValue:breadcrumbs forKey:@"breadcrumbs"];
|
|
479
|
+
|
|
385
480
|
resolve(serializedScope);
|
|
386
481
|
}
|
|
387
482
|
|
|
388
|
-
RCT_EXPORT_METHOD(fetchNativeAppStart
|
|
389
|
-
|
|
483
|
+
RCT_EXPORT_METHOD(fetchNativeAppStart
|
|
484
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
485
|
+
: (RCTPromiseRejectBlock)reject)
|
|
390
486
|
{
|
|
391
487
|
#if SENTRY_HAS_UIKIT
|
|
392
|
-
NSDictionary<NSString *, id> *measurements =
|
|
488
|
+
NSDictionary<NSString *, id> *measurements =
|
|
489
|
+
[PrivateSentrySDKOnly appStartMeasurementWithSpans];
|
|
393
490
|
if (measurements == nil) {
|
|
394
491
|
resolve(nil);
|
|
395
492
|
return;
|
|
396
493
|
}
|
|
397
494
|
|
|
398
|
-
NSMutableDictionary<NSString *, id> *mutableMeasurements =
|
|
399
|
-
|
|
495
|
+
NSMutableDictionary<NSString *, id> *mutableMeasurements =
|
|
496
|
+
[[NSMutableDictionary alloc] initWithDictionary:measurements];
|
|
497
|
+
[mutableMeasurements setValue:[NSNumber numberWithBool:hasFetchedAppStart]
|
|
498
|
+
forKey:@"has_fetched"];
|
|
400
499
|
|
|
401
500
|
// This is always set to true, as we would only allow an app start fetch to only happen once
|
|
402
501
|
// in the case of a JS bundle reload, we do not want it to be instrumented again.
|
|
@@ -408,8 +507,9 @@ RCT_EXPORT_METHOD(fetchNativeAppStart:(RCTPromiseResolveBlock)resolve
|
|
|
408
507
|
#endif
|
|
409
508
|
}
|
|
410
509
|
|
|
411
|
-
RCT_EXPORT_METHOD(fetchNativeFrames
|
|
412
|
-
|
|
510
|
+
RCT_EXPORT_METHOD(fetchNativeFrames
|
|
511
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
512
|
+
: (RCTPromiseRejectBlock)reject)
|
|
413
513
|
{
|
|
414
514
|
|
|
415
515
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
@@ -425,79 +525,82 @@ RCT_EXPORT_METHOD(fetchNativeFrames:(RCTPromiseResolveBlock)resolve
|
|
|
425
525
|
NSNumber *frozen = [NSNumber numberWithLong:frames.frozen];
|
|
426
526
|
NSNumber *slow = [NSNumber numberWithLong:frames.slow];
|
|
427
527
|
|
|
428
|
-
resolve(@{
|
|
429
|
-
@"totalFrames": total,
|
|
430
|
-
@"frozenFrames": frozen,
|
|
431
|
-
@"slowFrames": slow,
|
|
528
|
+
resolve(@ {
|
|
529
|
+
@"totalFrames" : total,
|
|
530
|
+
@"frozenFrames" : frozen,
|
|
531
|
+
@"slowFrames" : slow,
|
|
432
532
|
});
|
|
433
533
|
} else {
|
|
434
|
-
|
|
534
|
+
resolve(nil);
|
|
435
535
|
}
|
|
436
536
|
#else
|
|
437
537
|
resolve(nil);
|
|
438
538
|
#endif
|
|
439
539
|
}
|
|
440
540
|
|
|
441
|
-
RCT_EXPORT_METHOD(fetchNativeRelease
|
|
442
|
-
|
|
541
|
+
RCT_EXPORT_METHOD(fetchNativeRelease
|
|
542
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
543
|
+
: (RCTPromiseRejectBlock)reject)
|
|
443
544
|
{
|
|
444
545
|
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
|
|
445
|
-
resolve(@{
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
RCT_EXPORT_METHOD(captureEnvelope
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
546
|
+
resolve(@ {
|
|
547
|
+
@"id" : infoDict[@"CFBundleIdentifier"],
|
|
548
|
+
@"version" : infoDict[@"CFBundleShortVersionString"],
|
|
549
|
+
@"build" : infoDict[@"CFBundleVersion"],
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
RCT_EXPORT_METHOD(captureEnvelope
|
|
554
|
+
: (NSString *_Nonnull)rawBytes options
|
|
555
|
+
: (NSDictionary *_Nonnull)options resolve
|
|
556
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
557
|
+
: (RCTPromiseRejectBlock)reject)
|
|
456
558
|
{
|
|
457
559
|
NSData *data = [[NSData alloc] initWithBase64EncodedString:rawBytes options:0];
|
|
458
560
|
|
|
459
561
|
SentryEnvelope *envelope = [PrivateSentrySDKOnly envelopeWithData:data];
|
|
460
562
|
if (envelope == nil) {
|
|
461
|
-
reject(@"SentryReactNative"
|
|
563
|
+
reject(@"SentryReactNative", @"Failed to parse envelope from byte array.", nil);
|
|
462
564
|
return;
|
|
463
565
|
}
|
|
464
566
|
|
|
465
|
-
|
|
567
|
+
#if DEBUG
|
|
568
|
+
[PrivateSentrySDKOnly captureEnvelope:envelope];
|
|
569
|
+
#else
|
|
570
|
+
if ([[options objectForKey:@"hardCrashed"] boolValue]) {
|
|
571
|
+
// Storing to disk happens asynchronously with captureEnvelope
|
|
572
|
+
[PrivateSentrySDKOnly storeEnvelope:envelope];
|
|
573
|
+
} else {
|
|
466
574
|
[PrivateSentrySDKOnly captureEnvelope:envelope];
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
// Storing to disk happens asynchronously with captureEnvelope
|
|
470
|
-
[PrivateSentrySDKOnly storeEnvelope:envelope];
|
|
471
|
-
} else {
|
|
472
|
-
[PrivateSentrySDKOnly captureEnvelope:envelope];
|
|
473
|
-
}
|
|
474
|
-
#endif
|
|
575
|
+
}
|
|
576
|
+
#endif
|
|
475
577
|
resolve(@YES);
|
|
476
578
|
}
|
|
477
579
|
|
|
478
|
-
RCT_EXPORT_METHOD(captureScreenshot
|
|
479
|
-
|
|
580
|
+
RCT_EXPORT_METHOD(captureScreenshot
|
|
581
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
582
|
+
: (RCTPromiseRejectBlock)reject)
|
|
480
583
|
{
|
|
481
584
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
482
|
-
NSArray<NSData
|
|
585
|
+
NSArray<NSData *> *rawScreenshots = [PrivateSentrySDKOnly captureScreenshots];
|
|
483
586
|
NSMutableArray *screenshotsArray = [NSMutableArray arrayWithCapacity:[rawScreenshots count]];
|
|
484
587
|
|
|
485
588
|
int counter = 1;
|
|
486
|
-
for (NSData*
|
|
589
|
+
for (NSData *raw in rawScreenshots) {
|
|
487
590
|
NSMutableArray *screenshot = [NSMutableArray arrayWithCapacity:raw.length];
|
|
488
|
-
const char *bytes = (char*)
|
|
591
|
+
const char *bytes = (char *)[raw bytes];
|
|
489
592
|
for (int i = 0; i < [raw length]; i++) {
|
|
490
593
|
[screenshot addObject:[[NSNumber alloc] initWithChar:bytes[i]]];
|
|
491
594
|
}
|
|
492
595
|
|
|
493
|
-
NSString*
|
|
596
|
+
NSString *filename = @"screenshot.png";
|
|
494
597
|
if (counter > 1) {
|
|
495
598
|
filename = [NSString stringWithFormat:@"screenshot-%d.png", counter];
|
|
496
599
|
}
|
|
497
|
-
[screenshotsArray addObject:@{
|
|
498
|
-
@"data": screenshot,
|
|
499
|
-
@"contentType": @"image/png",
|
|
500
|
-
@"filename": filename,
|
|
600
|
+
[screenshotsArray addObject:@ {
|
|
601
|
+
@"data" : screenshot,
|
|
602
|
+
@"contentType" : @"image/png",
|
|
603
|
+
@"filename" : filename,
|
|
501
604
|
}];
|
|
502
605
|
counter++;
|
|
503
606
|
}
|
|
@@ -508,14 +611,15 @@ RCT_EXPORT_METHOD(captureScreenshot: (RCTPromiseResolveBlock)resolve
|
|
|
508
611
|
#endif
|
|
509
612
|
}
|
|
510
613
|
|
|
511
|
-
RCT_EXPORT_METHOD(fetchViewHierarchy
|
|
512
|
-
|
|
614
|
+
RCT_EXPORT_METHOD(fetchViewHierarchy
|
|
615
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
616
|
+
: (RCTPromiseRejectBlock)reject)
|
|
513
617
|
{
|
|
514
618
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
515
|
-
NSData *
|
|
619
|
+
NSData *rawViewHierarchy = [PrivateSentrySDKOnly captureViewHierarchy];
|
|
516
620
|
|
|
517
621
|
NSMutableArray *viewHierarchy = [NSMutableArray arrayWithCapacity:rawViewHierarchy.length];
|
|
518
|
-
const char *bytes = (char*)
|
|
622
|
+
const char *bytes = (char *)[rawViewHierarchy bytes];
|
|
519
623
|
for (int i = 0; i < [rawViewHierarchy length]; i++) {
|
|
520
624
|
[viewHierarchy addObject:[[NSNumber alloc] initWithChar:bytes[i]]];
|
|
521
625
|
}
|
|
@@ -526,16 +630,13 @@ RCT_EXPORT_METHOD(fetchViewHierarchy: (RCTPromiseResolveBlock)resolve
|
|
|
526
630
|
#endif
|
|
527
631
|
}
|
|
528
632
|
|
|
529
|
-
|
|
530
|
-
RCT_EXPORT_METHOD(setUser:(NSDictionary *)userKeys
|
|
531
|
-
otherUserKeys:(NSDictionary *)userDataKeys
|
|
532
|
-
)
|
|
633
|
+
RCT_EXPORT_METHOD(setUser : (NSDictionary *)userKeys otherUserKeys : (NSDictionary *)userDataKeys)
|
|
533
634
|
{
|
|
534
|
-
[SentrySDK configureScope:^(SentryScope *
|
|
635
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
|
|
535
636
|
if (nil == userKeys && nil == userDataKeys) {
|
|
536
637
|
[scope setUser:nil];
|
|
537
638
|
} else {
|
|
538
|
-
SentryUser*
|
|
639
|
+
SentryUser *userInstance = [[SentryUser alloc] init];
|
|
539
640
|
|
|
540
641
|
if (nil != userKeys) {
|
|
541
642
|
[userInstance setUserId:userKeys[@"id"]];
|
|
@@ -554,9 +655,9 @@ RCT_EXPORT_METHOD(setUser:(NSDictionary *)userKeys
|
|
|
554
655
|
}];
|
|
555
656
|
}
|
|
556
657
|
|
|
557
|
-
RCT_EXPORT_METHOD(addBreadcrumb:(NSDictionary *)breadcrumb)
|
|
658
|
+
RCT_EXPORT_METHOD(addBreadcrumb : (NSDictionary *)breadcrumb)
|
|
558
659
|
{
|
|
559
|
-
[SentrySDK configureScope:^(SentryScope *
|
|
660
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
|
|
560
661
|
[scope addBreadcrumb:[RNSentryBreadcrumb from:breadcrumb]];
|
|
561
662
|
}];
|
|
562
663
|
|
|
@@ -565,33 +666,27 @@ RCT_EXPORT_METHOD(addBreadcrumb:(NSDictionary *)breadcrumb)
|
|
|
565
666
|
if (screen != nil) {
|
|
566
667
|
[PrivateSentrySDKOnly setCurrentScreen:screen];
|
|
567
668
|
}
|
|
568
|
-
#endif //SENTRY_HAS_UIKIT
|
|
669
|
+
#endif // SENTRY_HAS_UIKIT
|
|
569
670
|
}
|
|
570
671
|
|
|
571
|
-
RCT_EXPORT_METHOD(clearBreadcrumbs)
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
}];
|
|
672
|
+
RCT_EXPORT_METHOD(clearBreadcrumbs)
|
|
673
|
+
{
|
|
674
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) { [scope clearBreadcrumbs]; }];
|
|
575
675
|
}
|
|
576
676
|
|
|
577
|
-
RCT_EXPORT_METHOD(setExtra:(NSString *)key
|
|
578
|
-
extra:(NSString *)extra
|
|
579
|
-
)
|
|
677
|
+
RCT_EXPORT_METHOD(setExtra : (NSString *)key extra : (NSString *)extra)
|
|
580
678
|
{
|
|
581
|
-
[SentrySDK
|
|
582
|
-
[scope setExtraValue:extra forKey:key];
|
|
583
|
-
}];
|
|
679
|
+
[SentrySDK
|
|
680
|
+
configureScope:^(SentryScope *_Nonnull scope) { [scope setExtraValue:extra forKey:key]; }];
|
|
584
681
|
}
|
|
585
682
|
|
|
586
|
-
RCT_EXPORT_METHOD(setContext:(NSString *)key
|
|
587
|
-
context:(NSDictionary *)context
|
|
588
|
-
)
|
|
683
|
+
RCT_EXPORT_METHOD(setContext : (NSString *)key context : (NSDictionary *)context)
|
|
589
684
|
{
|
|
590
685
|
if (key == nil) {
|
|
591
686
|
return;
|
|
592
687
|
}
|
|
593
688
|
|
|
594
|
-
[SentrySDK configureScope:^(SentryScope *
|
|
689
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
|
|
595
690
|
if (context == nil) {
|
|
596
691
|
[scope removeContextForKey:key];
|
|
597
692
|
} else {
|
|
@@ -600,25 +695,20 @@ RCT_EXPORT_METHOD(setContext:(NSString *)key
|
|
|
600
695
|
}];
|
|
601
696
|
}
|
|
602
697
|
|
|
603
|
-
RCT_EXPORT_METHOD(setTag:(NSString *)key
|
|
604
|
-
value:(NSString *)value
|
|
605
|
-
)
|
|
698
|
+
RCT_EXPORT_METHOD(setTag : (NSString *)key value : (NSString *)value)
|
|
606
699
|
{
|
|
607
|
-
[SentrySDK
|
|
608
|
-
[scope setTagValue:value forKey:key];
|
|
609
|
-
}];
|
|
700
|
+
[SentrySDK
|
|
701
|
+
configureScope:^(SentryScope *_Nonnull scope) { [scope setTagValue:value forKey:key]; }];
|
|
610
702
|
}
|
|
611
703
|
|
|
612
|
-
RCT_EXPORT_METHOD(crash)
|
|
613
|
-
{
|
|
614
|
-
[SentrySDK crash];
|
|
615
|
-
}
|
|
704
|
+
RCT_EXPORT_METHOD(crash) { [SentrySDK crash]; }
|
|
616
705
|
|
|
617
|
-
RCT_EXPORT_METHOD(closeNativeSdk
|
|
618
|
-
|
|
706
|
+
RCT_EXPORT_METHOD(closeNativeSdk
|
|
707
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
708
|
+
: (RCTPromiseRejectBlock)reject)
|
|
619
709
|
{
|
|
620
|
-
|
|
621
|
-
|
|
710
|
+
[SentrySDK close];
|
|
711
|
+
resolve(@YES);
|
|
622
712
|
}
|
|
623
713
|
|
|
624
714
|
RCT_EXPORT_METHOD(disableNativeFramesTracking)
|
|
@@ -634,70 +724,76 @@ RCT_EXPORT_METHOD(enableNativeFramesTracking)
|
|
|
634
724
|
// the 'tracesSampleRate' or 'tracesSampler' option.
|
|
635
725
|
}
|
|
636
726
|
|
|
637
|
-
RCT_EXPORT_METHOD(captureReplay
|
|
638
|
-
|
|
639
|
-
|
|
727
|
+
RCT_EXPORT_METHOD(captureReplay
|
|
728
|
+
: (BOOL)isHardCrash resolver
|
|
729
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
730
|
+
: (RCTPromiseRejectBlock)reject)
|
|
640
731
|
{
|
|
641
732
|
#if SENTRY_TARGET_REPLAY_SUPPORTED
|
|
642
|
-
|
|
643
|
-
|
|
733
|
+
[PrivateSentrySDKOnly captureReplay];
|
|
734
|
+
resolve([PrivateSentrySDKOnly getReplayId]);
|
|
644
735
|
#else
|
|
645
|
-
|
|
736
|
+
resolve(nil);
|
|
646
737
|
#endif
|
|
647
738
|
}
|
|
648
739
|
|
|
649
740
|
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getCurrentReplayId)
|
|
650
741
|
{
|
|
651
742
|
#if SENTRY_TARGET_REPLAY_SUPPORTED
|
|
652
|
-
|
|
743
|
+
return [PrivateSentrySDKOnly getReplayId];
|
|
653
744
|
#else
|
|
654
|
-
|
|
745
|
+
return nil;
|
|
655
746
|
#endif
|
|
656
747
|
}
|
|
657
748
|
|
|
658
|
-
static NSString*
|
|
659
|
-
static SentryId*
|
|
749
|
+
static NSString *const enabledProfilingMessage = @"Enable Hermes to use Sentry Profiling.";
|
|
750
|
+
static SentryId *nativeProfileTraceId = nil;
|
|
660
751
|
static uint64_t nativeProfileStartTime = 0;
|
|
661
752
|
|
|
662
|
-
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, startProfiling: (BOOL)platformProfilers)
|
|
753
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, startProfiling : (BOOL)platformProfilers)
|
|
663
754
|
{
|
|
664
755
|
#if SENTRY_PROFILING_ENABLED
|
|
665
756
|
try {
|
|
666
757
|
facebook::hermes::HermesRuntime::enableSamplingProfiler();
|
|
667
758
|
if (nativeProfileTraceId == nil && nativeProfileStartTime == 0 && platformProfilers) {
|
|
668
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
759
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
669
760
|
nativeProfileTraceId = [RNSentryId newId];
|
|
670
|
-
nativeProfileStartTime =
|
|
671
|
-
|
|
761
|
+
nativeProfileStartTime =
|
|
762
|
+
[PrivateSentrySDKOnly startProfilerForTrace:nativeProfileTraceId];
|
|
763
|
+
# endif
|
|
672
764
|
} else {
|
|
673
765
|
if (!platformProfilers) {
|
|
674
766
|
NSLog(@"Native profiling is disabled. Only starting Hermes profiling.");
|
|
675
767
|
} else {
|
|
676
|
-
NSLog(@"Native profiling already in progress. Currently existing trace: %@",
|
|
768
|
+
NSLog(@"Native profiling already in progress. Currently existing trace: %@",
|
|
769
|
+
nativeProfileTraceId);
|
|
677
770
|
}
|
|
678
771
|
}
|
|
679
|
-
return @{
|
|
680
|
-
} catch (const std::exception&
|
|
772
|
+
return @{@"started" : @YES};
|
|
773
|
+
} catch (const std::exception &ex) {
|
|
681
774
|
if (nativeProfileTraceId != nil) {
|
|
682
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
683
|
-
[PrivateSentrySDKOnly discardProfilerForTrace:
|
|
684
|
-
#endif
|
|
775
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
776
|
+
[PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
|
|
777
|
+
# endif
|
|
685
778
|
nativeProfileTraceId = nil;
|
|
686
779
|
}
|
|
687
780
|
nativeProfileStartTime = 0;
|
|
688
|
-
return @{
|
|
781
|
+
return @ {
|
|
782
|
+
@"error" : [NSString stringWithCString:ex.what()
|
|
783
|
+
encoding:[NSString defaultCStringEncoding]]
|
|
784
|
+
};
|
|
689
785
|
} catch (...) {
|
|
690
786
|
if (nativeProfileTraceId != nil) {
|
|
691
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
692
|
-
[PrivateSentrySDKOnly discardProfilerForTrace:
|
|
693
|
-
#endif
|
|
787
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
788
|
+
[PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
|
|
789
|
+
# endif
|
|
694
790
|
nativeProfileTraceId = nil;
|
|
695
791
|
}
|
|
696
792
|
nativeProfileStartTime = 0;
|
|
697
|
-
return @{ @"error": @"Failed to start profiling" };
|
|
793
|
+
return @ { @"error" : @"Failed to start profiling" };
|
|
698
794
|
}
|
|
699
795
|
#else
|
|
700
|
-
return @{ @"error": enabledProfilingMessage };
|
|
796
|
+
return @ { @"error" : enabledProfilingMessage };
|
|
701
797
|
#endif
|
|
702
798
|
}
|
|
703
799
|
|
|
@@ -705,12 +801,14 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, stopProfiling)
|
|
|
705
801
|
{
|
|
706
802
|
#if SENTRY_PROFILING_ENABLED
|
|
707
803
|
try {
|
|
708
|
-
NSDictionary<NSString *, id> *
|
|
804
|
+
NSDictionary<NSString *, id> *nativeProfile = nil;
|
|
709
805
|
if (nativeProfileTraceId != nil && nativeProfileStartTime != 0) {
|
|
710
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
806
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
711
807
|
uint64_t nativeProfileStopTime = clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
|
|
712
|
-
nativeProfile = [PrivateSentrySDKOnly collectProfileBetween:nativeProfileStartTime
|
|
713
|
-
|
|
808
|
+
nativeProfile = [PrivateSentrySDKOnly collectProfileBetween:nativeProfileStartTime
|
|
809
|
+
and:nativeProfileStopTime
|
|
810
|
+
forTrace:nativeProfileTraceId];
|
|
811
|
+
# endif
|
|
714
812
|
}
|
|
715
813
|
// Cleanup native profiles
|
|
716
814
|
nativeProfileTraceId = nil;
|
|
@@ -722,57 +820,66 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, stopProfiling)
|
|
|
722
820
|
facebook::hermes::HermesRuntime::dumpSampledTraceToStream(ss);
|
|
723
821
|
|
|
724
822
|
std::string s = ss.str();
|
|
725
|
-
NSString *data = [NSString stringWithCString:s.c_str()
|
|
823
|
+
NSString *data = [NSString stringWithCString:s.c_str()
|
|
824
|
+
encoding:[NSString defaultCStringEncoding]];
|
|
726
825
|
|
|
727
|
-
#if SENTRY_PROFILING_DEBUG_ENABLED
|
|
826
|
+
# if SENTRY_PROFILING_DEBUG_ENABLED
|
|
728
827
|
NSString *rawProfileFileName = @"hermes.profile";
|
|
729
828
|
NSError *error = nil;
|
|
730
|
-
NSString *rawProfileFilePath =
|
|
731
|
-
|
|
829
|
+
NSString *rawProfileFilePath =
|
|
830
|
+
[NSTemporaryDirectory() stringByAppendingPathComponent:rawProfileFileName];
|
|
831
|
+
if (![data writeToFile:rawProfileFilePath
|
|
832
|
+
atomically:YES
|
|
833
|
+
encoding:NSUTF8StringEncoding
|
|
834
|
+
error:&error]) {
|
|
732
835
|
NSLog(@"Error writing Raw Hermes Profile to %@: %@", rawProfileFilePath, error);
|
|
733
836
|
} else {
|
|
734
837
|
NSLog(@"Raw Hermes Profile saved to %@", rawProfileFilePath);
|
|
735
838
|
}
|
|
736
|
-
#endif
|
|
839
|
+
# endif
|
|
737
840
|
|
|
738
841
|
if (data == nil) {
|
|
739
|
-
|
|
842
|
+
return @ { @"error" : @"Failed to retrieve Hermes profile." };
|
|
740
843
|
}
|
|
741
844
|
|
|
742
845
|
if (nativeProfile == nil) {
|
|
743
|
-
|
|
846
|
+
return @ { @"profile" : data };
|
|
744
847
|
}
|
|
745
848
|
|
|
746
|
-
return @{
|
|
747
|
-
|
|
748
|
-
|
|
849
|
+
return @ {
|
|
850
|
+
@"profile" : data,
|
|
851
|
+
@"nativeProfile" : nativeProfile,
|
|
749
852
|
};
|
|
750
|
-
} catch (const std::exception&
|
|
853
|
+
} catch (const std::exception &ex) {
|
|
751
854
|
if (nativeProfileTraceId != nil) {
|
|
752
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
753
|
-
|
|
754
|
-
#endif
|
|
755
|
-
|
|
855
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
856
|
+
[PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
|
|
857
|
+
# endif
|
|
858
|
+
nativeProfileTraceId = nil;
|
|
756
859
|
}
|
|
757
860
|
nativeProfileStartTime = 0;
|
|
758
|
-
return @{
|
|
861
|
+
return @ {
|
|
862
|
+
@"error" : [NSString stringWithCString:ex.what()
|
|
863
|
+
encoding:[NSString defaultCStringEncoding]]
|
|
864
|
+
};
|
|
759
865
|
} catch (...) {
|
|
760
866
|
if (nativeProfileTraceId != nil) {
|
|
761
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
762
|
-
|
|
763
|
-
#endif
|
|
764
|
-
|
|
867
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
868
|
+
[PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
|
|
869
|
+
# endif
|
|
870
|
+
nativeProfileTraceId = nil;
|
|
765
871
|
}
|
|
766
872
|
nativeProfileStartTime = 0;
|
|
767
|
-
return @{ @"error": @"Failed to stop profiling" };
|
|
873
|
+
return @ { @"error" : @"Failed to stop profiling" };
|
|
768
874
|
}
|
|
769
875
|
#else
|
|
770
|
-
return @{ @"error": enabledProfilingMessage };
|
|
876
|
+
return @ { @"error" : enabledProfilingMessage };
|
|
771
877
|
#endif
|
|
772
878
|
}
|
|
773
879
|
|
|
774
|
-
RCT_EXPORT_METHOD(crashedLastRun
|
|
775
|
-
|
|
880
|
+
RCT_EXPORT_METHOD(crashedLastRun
|
|
881
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
882
|
+
: (RCTPromiseRejectBlock)reject)
|
|
776
883
|
{
|
|
777
884
|
resolve(@([SentrySDK crashedLastRun]));
|
|
778
885
|
}
|
|
@@ -786,4 +893,11 @@ RCT_EXPORT_METHOD(crashedLastRun:(RCTPromiseResolveBlock)resolve
|
|
|
786
893
|
}
|
|
787
894
|
#endif
|
|
788
895
|
|
|
896
|
+
RCT_EXPORT_METHOD(getNewScreenTimeToDisplay
|
|
897
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
898
|
+
: (RCTPromiseRejectBlock)reject)
|
|
899
|
+
{
|
|
900
|
+
[_timeToDisplay getTimeToDisplay:resolve];
|
|
901
|
+
}
|
|
902
|
+
|
|
789
903
|
@end
|