@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/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,21 +140,24 @@ 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
|
}
|
|
@@ -158,58 +172,79 @@ RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options
|
|
|
158
172
|
}
|
|
159
173
|
}
|
|
160
174
|
|
|
175
|
+
// Set spotlight option
|
|
176
|
+
if ([mutableOptions valueForKey:@"spotlight"] != nil) {
|
|
177
|
+
id spotlightValue = [mutableOptions valueForKey:@"spotlight"];
|
|
178
|
+
if ([spotlightValue isKindOfClass:[NSString class]]) {
|
|
179
|
+
NSLog(@"Using Spotlight on address: %@", spotlightValue);
|
|
180
|
+
sentryOptions.enableSpotlight = true;
|
|
181
|
+
sentryOptions.spotlightUrl = spotlightValue;
|
|
182
|
+
} else if ([spotlightValue isKindOfClass:[NSNumber class]]) {
|
|
183
|
+
sentryOptions.enableSpotlight = [spotlightValue boolValue];
|
|
184
|
+
id defaultSpotlightUrl = [mutableOptions valueForKey:@"defaultSidecarUrl"];
|
|
185
|
+
if (defaultSpotlightUrl != nil) {
|
|
186
|
+
sentryOptions.spotlightUrl = defaultSpotlightUrl;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
161
191
|
// Enable the App start and Frames tracking measurements
|
|
162
192
|
if ([mutableOptions valueForKey:@"enableAutoPerformanceTracing"] != nil) {
|
|
163
|
-
BOOL enableAutoPerformanceTracing =
|
|
193
|
+
BOOL enableAutoPerformanceTracing =
|
|
194
|
+
[mutableOptions[@"enableAutoPerformanceTracing"] boolValue];
|
|
164
195
|
PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = enableAutoPerformanceTracing;
|
|
165
196
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
166
197
|
PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = enableAutoPerformanceTracing;
|
|
167
198
|
#endif
|
|
168
199
|
}
|
|
169
200
|
|
|
201
|
+
// Failed requests can only be enabled in one SDK to avoid duplicates
|
|
202
|
+
sentryOptions.enableCaptureFailedRequests = @NO;
|
|
203
|
+
|
|
170
204
|
return sentryOptions;
|
|
171
205
|
}
|
|
172
206
|
|
|
173
|
-
- (void)setEventOriginTag:(SentryEvent *)event
|
|
174
|
-
|
|
175
|
-
|
|
207
|
+
- (void)setEventOriginTag:(SentryEvent *)event
|
|
208
|
+
{
|
|
209
|
+
if (event.sdk != nil) {
|
|
210
|
+
NSString *sdkName = event.sdk[@"name"];
|
|
176
211
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
212
|
+
// If the event is from react native, it gets set
|
|
213
|
+
// there and we do not handle it here.
|
|
214
|
+
if ([sdkName isEqual:nativeSdkName]) {
|
|
215
|
+
[self setEventEnvironmentTag:event origin:@"ios" environment:@"native"];
|
|
216
|
+
}
|
|
181
217
|
}
|
|
182
|
-
}
|
|
183
218
|
}
|
|
184
219
|
|
|
185
220
|
- (void)setEventEnvironmentTag:(SentryEvent *)event
|
|
186
221
|
origin:(NSString *)origin
|
|
187
|
-
environment:(NSString *)environment
|
|
188
|
-
|
|
222
|
+
environment:(NSString *)environment
|
|
223
|
+
{
|
|
224
|
+
NSMutableDictionary *newTags = [NSMutableDictionary new];
|
|
189
225
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
226
|
+
if (nil != event.tags && [event.tags count] > 0) {
|
|
227
|
+
[newTags addEntriesFromDictionary:event.tags];
|
|
228
|
+
}
|
|
229
|
+
if (nil != origin) {
|
|
230
|
+
[newTags setValue:origin forKey:@"event.origin"];
|
|
231
|
+
}
|
|
232
|
+
if (nil != environment) {
|
|
233
|
+
[newTags setValue:environment forKey:@"event.environment"];
|
|
234
|
+
}
|
|
199
235
|
|
|
200
|
-
|
|
236
|
+
event.tags = newTags;
|
|
201
237
|
}
|
|
202
238
|
|
|
203
|
-
RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking
|
|
204
|
-
|
|
239
|
+
RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking
|
|
240
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
241
|
+
: (RCTPromiseRejectBlock)reject)
|
|
205
242
|
{
|
|
206
243
|
#if SENTRY_HAS_UIKIT
|
|
207
244
|
if ([[NSThread currentThread] isMainThread]) {
|
|
208
245
|
[RNSentryRNSScreen swizzleViewDidAppear];
|
|
209
246
|
} else {
|
|
210
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
211
|
-
[RNSentryRNSScreen swizzleViewDidAppear];
|
|
212
|
-
});
|
|
247
|
+
dispatch_async(dispatch_get_main_queue(), ^{ [RNSentryRNSScreen swizzleViewDidAppear]; });
|
|
213
248
|
}
|
|
214
249
|
|
|
215
250
|
[self initFramesTracking];
|
|
@@ -217,48 +252,57 @@ RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking:(RCTPromiseResolveBl
|
|
|
217
252
|
resolve(nil);
|
|
218
253
|
}
|
|
219
254
|
|
|
220
|
-
- (void)initFramesTracking
|
|
255
|
+
- (void)initFramesTracking
|
|
256
|
+
{
|
|
221
257
|
#if SENTRY_HAS_UIKIT
|
|
222
258
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
259
|
+
RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) {
|
|
260
|
+
if (self->hasListeners) {
|
|
261
|
+
[self
|
|
262
|
+
sendEventWithName:RNSentryNewFrameEvent
|
|
263
|
+
body:@{ @"newFrameTimestampInSeconds" : newFrameTimestampInSeconds }];
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
[[RNSentryDependencyContainer sharedInstance]
|
|
267
|
+
initializeFramesTrackerListenerWith:emitNewFrameEvent];
|
|
229
268
|
#endif
|
|
230
269
|
}
|
|
231
270
|
|
|
232
271
|
// Will be called when this module's first listener is added.
|
|
233
|
-
-(void)startObserving
|
|
272
|
+
- (void)startObserving
|
|
273
|
+
{
|
|
234
274
|
hasListeners = YES;
|
|
235
275
|
}
|
|
236
276
|
|
|
237
277
|
// Will be called when this module's last listener is removed, or on dealloc.
|
|
238
|
-
-(void)stopObserving
|
|
278
|
+
- (void)stopObserving
|
|
279
|
+
{
|
|
239
280
|
hasListeners = NO;
|
|
240
281
|
}
|
|
241
282
|
|
|
242
|
-
- (NSArray<NSString *> *)supportedEvents
|
|
243
|
-
|
|
283
|
+
- (NSArray<NSString *> *)supportedEvents
|
|
284
|
+
{
|
|
285
|
+
return @[ RNSentryNewFrameEvent ];
|
|
244
286
|
}
|
|
245
287
|
|
|
246
|
-
RCT_EXPORT_METHOD(fetchNativeSdkInfo
|
|
247
|
-
|
|
288
|
+
RCT_EXPORT_METHOD(fetchNativeSdkInfo
|
|
289
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
290
|
+
: (RCTPromiseRejectBlock)reject)
|
|
248
291
|
{
|
|
249
|
-
resolve(@{
|
|
250
|
-
@"name": PrivateSentrySDKOnly.getSdkName,
|
|
251
|
-
@"version": PrivateSentrySDKOnly.getSdkVersionString
|
|
252
|
-
|
|
292
|
+
resolve(@ {
|
|
293
|
+
@"name" : PrivateSentrySDKOnly.getSdkName,
|
|
294
|
+
@"version" : PrivateSentrySDKOnly.getSdkVersionString
|
|
295
|
+
});
|
|
253
296
|
}
|
|
254
297
|
|
|
255
|
-
RCT_EXPORT_METHOD(fetchModules
|
|
256
|
-
|
|
298
|
+
RCT_EXPORT_METHOD(fetchModules
|
|
299
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
300
|
+
: (RCTPromiseRejectBlock)reject)
|
|
257
301
|
{
|
|
258
302
|
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"modules" ofType:@"json"];
|
|
259
|
-
NSString*
|
|
260
|
-
|
|
261
|
-
|
|
303
|
+
NSString *modulesString = [NSString stringWithContentsOfFile:filePath
|
|
304
|
+
encoding:NSUTF8StringEncoding
|
|
305
|
+
error:nil];
|
|
262
306
|
resolve(modulesString);
|
|
263
307
|
}
|
|
264
308
|
|
|
@@ -268,79 +312,90 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, fetchNativePackageName)
|
|
|
268
312
|
return packageName;
|
|
269
313
|
}
|
|
270
314
|
|
|
271
|
-
- (NSDictionary*)
|
|
272
|
-
symbolicate:
|
|
315
|
+
- (NSDictionary *)fetchNativeStackFramesBy:(NSArray<NSNumber *> *)instructionsAddr
|
|
316
|
+
symbolicate:(SymbolicateCallbackType)symbolicate
|
|
273
317
|
{
|
|
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
|
-
|
|
318
|
+
BOOL shouldSymbolicateLocally = [SentrySDK.options debug];
|
|
319
|
+
NSString *appPackageName = [[NSBundle mainBundle] executablePath];
|
|
320
|
+
|
|
321
|
+
NSMutableSet<NSString *> *_Nonnull imagesAddrToRetrieveDebugMetaImages =
|
|
322
|
+
[[NSMutableSet alloc] init];
|
|
323
|
+
NSMutableArray<NSDictionary<NSString *, id> *> *_Nonnull serializedFrames =
|
|
324
|
+
[[NSMutableArray alloc] init];
|
|
325
|
+
|
|
326
|
+
for (NSNumber *addr in instructionsAddr) {
|
|
327
|
+
SentryBinaryImageInfo *_Nullable image = [[[SentryDependencyContainer sharedInstance]
|
|
328
|
+
binaryImageCache] imageByAddress:[addr unsignedLongLongValue]];
|
|
329
|
+
if (image != nil) {
|
|
330
|
+
NSString *imageAddr = sentry_formatHexAddressUInt64([image address]);
|
|
331
|
+
[imagesAddrToRetrieveDebugMetaImages addObject:imageAddr];
|
|
332
|
+
|
|
333
|
+
NSDictionary<NSString *, id> *_Nonnull nativeFrame = @{
|
|
334
|
+
@"platform" : @"cocoa",
|
|
335
|
+
@"instruction_addr" : sentry_formatHexAddress(addr),
|
|
336
|
+
@"package" : [image name],
|
|
337
|
+
@"image_addr" : imageAddr,
|
|
338
|
+
@"in_app" : [NSNumber numberWithBool:[appPackageName isEqualToString:[image name]]],
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
if (shouldSymbolicateLocally) {
|
|
342
|
+
Dl_info symbolsBuffer;
|
|
343
|
+
bool symbols_succeed = false;
|
|
344
|
+
symbols_succeed
|
|
345
|
+
= symbolicate((void *)[addr unsignedLongLongValue], &symbolsBuffer) != 0;
|
|
346
|
+
if (symbols_succeed) {
|
|
347
|
+
NSMutableDictionary<NSString *, id> *_Nonnull symbolicated
|
|
348
|
+
= nativeFrame.mutableCopy;
|
|
349
|
+
symbolicated[@"symbol_addr"]
|
|
350
|
+
= sentry_formatHexAddressUInt64((uintptr_t)symbolsBuffer.dli_saddr);
|
|
351
|
+
symbolicated[@"function"] = [NSString stringWithCString:symbolsBuffer.dli_sname
|
|
352
|
+
encoding:NSUTF8StringEncoding];
|
|
353
|
+
|
|
354
|
+
nativeFrame = symbolicated;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
302
357
|
|
|
303
|
-
|
|
358
|
+
[serializedFrames addObject:nativeFrame];
|
|
359
|
+
} else {
|
|
360
|
+
[serializedFrames addObject:@{
|
|
361
|
+
@"platform" : @"cocoa",
|
|
362
|
+
@"instruction_addr" : sentry_formatHexAddress(addr),
|
|
363
|
+
}];
|
|
304
364
|
}
|
|
305
|
-
|
|
365
|
+
}
|
|
306
366
|
|
|
307
|
-
|
|
367
|
+
if (shouldSymbolicateLocally) {
|
|
368
|
+
return @{
|
|
369
|
+
@"frames" : serializedFrames,
|
|
370
|
+
};
|
|
308
371
|
} else {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
@"instruction_addr": sentry_formatHexAddress(addr),
|
|
312
|
-
}];
|
|
313
|
-
}
|
|
314
|
-
}
|
|
372
|
+
NSMutableArray<NSDictionary<NSString *, id> *> *_Nonnull serializedDebugMetaImages =
|
|
373
|
+
[[NSMutableArray alloc] init];
|
|
315
374
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
};
|
|
320
|
-
} else {
|
|
321
|
-
NSMutableArray<NSDictionary<NSString *, id> *> * _Nonnull serializedDebugMetaImages = [[NSMutableArray alloc] init];
|
|
375
|
+
NSArray<SentryDebugMeta *> *debugMetaImages =
|
|
376
|
+
[[[SentryDependencyContainer sharedInstance] debugImageProvider]
|
|
377
|
+
getDebugImagesForImageAddressesFromCache:imagesAddrToRetrieveDebugMetaImages];
|
|
322
378
|
|
|
323
|
-
|
|
379
|
+
for (SentryDebugMeta *debugImage in debugMetaImages) {
|
|
380
|
+
[serializedDebugMetaImages addObject:[debugImage serialize]];
|
|
381
|
+
}
|
|
324
382
|
|
|
325
|
-
|
|
326
|
-
|
|
383
|
+
return @{
|
|
384
|
+
@"frames" : serializedFrames,
|
|
385
|
+
@"debugMetaImages" : serializedDebugMetaImages,
|
|
386
|
+
};
|
|
327
387
|
}
|
|
328
|
-
|
|
329
|
-
return @{
|
|
330
|
-
@"frames": serializedFrames,
|
|
331
|
-
@"debugMetaImages": serializedDebugMetaImages,
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
388
|
}
|
|
335
389
|
|
|
336
|
-
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy
|
|
390
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy
|
|
391
|
+
: (NSArray *)instructionsAddr)
|
|
337
392
|
{
|
|
338
|
-
|
|
339
|
-
symbolicate:dladdr];
|
|
393
|
+
return [self fetchNativeStackFramesBy:instructionsAddr symbolicate:dladdr];
|
|
340
394
|
}
|
|
341
395
|
|
|
342
|
-
RCT_EXPORT_METHOD(fetchNativeDeviceContexts
|
|
343
|
-
|
|
396
|
+
RCT_EXPORT_METHOD(fetchNativeDeviceContexts
|
|
397
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
398
|
+
: (RCTPromiseRejectBlock)reject)
|
|
344
399
|
{
|
|
345
400
|
if (PrivateSentrySDKOnly.options.debug) {
|
|
346
401
|
NSLog(@"Bridge call to: deviceContexts");
|
|
@@ -348,36 +403,41 @@ RCT_EXPORT_METHOD(fetchNativeDeviceContexts:(RCTPromiseResolveBlock)resolve
|
|
|
348
403
|
__block NSMutableDictionary<NSString *, id> *serializedScope;
|
|
349
404
|
// Temp work around until sorted out this API in sentry-cocoa.
|
|
350
405
|
// TODO: If the callback isnt' executed the promise wouldn't be resolved.
|
|
351
|
-
[SentrySDK configureScope:^(SentryScope *
|
|
406
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
|
|
352
407
|
serializedScope = [[scope serialize] mutableCopy];
|
|
353
408
|
|
|
354
|
-
NSDictionary<NSString *, id>
|
|
409
|
+
NSDictionary<NSString *, id> *user = [serializedScope valueForKey:@"user"];
|
|
355
410
|
if (user == nil) {
|
|
356
|
-
[serializedScope
|
|
357
|
-
|
|
358
|
-
forKey:@"user"];
|
|
411
|
+
[serializedScope setValue:@ { @"id" : PrivateSentrySDKOnly.installationID }
|
|
412
|
+
forKey:@"user"];
|
|
359
413
|
}
|
|
360
414
|
|
|
361
415
|
if (PrivateSentrySDKOnly.options.debug) {
|
|
362
|
-
NSData *data = [NSJSONSerialization dataWithJSONObject:serializedScope
|
|
363
|
-
|
|
416
|
+
NSData *data = [NSJSONSerialization dataWithJSONObject:serializedScope
|
|
417
|
+
options:0
|
|
418
|
+
error:nil];
|
|
419
|
+
NSString *debugContext = [[NSString alloc] initWithData:data
|
|
420
|
+
encoding:NSUTF8StringEncoding];
|
|
364
421
|
NSLog(@"Contexts: %@", debugContext);
|
|
365
422
|
}
|
|
366
423
|
}];
|
|
367
424
|
|
|
368
425
|
NSDictionary<NSString *, id> *extraContext = [PrivateSentrySDKOnly getExtraContext];
|
|
369
|
-
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *contexts =
|
|
426
|
+
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *contexts =
|
|
427
|
+
[serializedScope[@"context"] mutableCopy];
|
|
370
428
|
|
|
371
429
|
if (extraContext && [extraContext[@"device"] isKindOfClass:[NSDictionary class]]) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
430
|
+
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *deviceContext =
|
|
431
|
+
[contexts[@"device"] mutableCopy];
|
|
432
|
+
[deviceContext addEntriesFromDictionary:extraContext[@"device"]];
|
|
433
|
+
[contexts setValue:deviceContext forKey:@"device"];
|
|
375
434
|
}
|
|
376
435
|
|
|
377
436
|
if (extraContext && [extraContext[@"app"] isKindOfClass:[NSDictionary class]]) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
437
|
+
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *appContext =
|
|
438
|
+
[contexts[@"app"] mutableCopy];
|
|
439
|
+
[appContext addEntriesFromDictionary:extraContext[@"app"]];
|
|
440
|
+
[contexts setValue:appContext forKey:@"app"];
|
|
381
441
|
}
|
|
382
442
|
|
|
383
443
|
[serializedScope setValue:contexts forKey:@"contexts"];
|
|
@@ -385,18 +445,22 @@ RCT_EXPORT_METHOD(fetchNativeDeviceContexts:(RCTPromiseResolveBlock)resolve
|
|
|
385
445
|
resolve(serializedScope);
|
|
386
446
|
}
|
|
387
447
|
|
|
388
|
-
RCT_EXPORT_METHOD(fetchNativeAppStart
|
|
389
|
-
|
|
448
|
+
RCT_EXPORT_METHOD(fetchNativeAppStart
|
|
449
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
450
|
+
: (RCTPromiseRejectBlock)reject)
|
|
390
451
|
{
|
|
391
452
|
#if SENTRY_HAS_UIKIT
|
|
392
|
-
NSDictionary<NSString *, id> *measurements =
|
|
453
|
+
NSDictionary<NSString *, id> *measurements =
|
|
454
|
+
[PrivateSentrySDKOnly appStartMeasurementWithSpans];
|
|
393
455
|
if (measurements == nil) {
|
|
394
456
|
resolve(nil);
|
|
395
457
|
return;
|
|
396
458
|
}
|
|
397
459
|
|
|
398
|
-
NSMutableDictionary<NSString *, id> *mutableMeasurements =
|
|
399
|
-
|
|
460
|
+
NSMutableDictionary<NSString *, id> *mutableMeasurements =
|
|
461
|
+
[[NSMutableDictionary alloc] initWithDictionary:measurements];
|
|
462
|
+
[mutableMeasurements setValue:[NSNumber numberWithBool:hasFetchedAppStart]
|
|
463
|
+
forKey:@"has_fetched"];
|
|
400
464
|
|
|
401
465
|
// This is always set to true, as we would only allow an app start fetch to only happen once
|
|
402
466
|
// in the case of a JS bundle reload, we do not want it to be instrumented again.
|
|
@@ -408,8 +472,9 @@ RCT_EXPORT_METHOD(fetchNativeAppStart:(RCTPromiseResolveBlock)resolve
|
|
|
408
472
|
#endif
|
|
409
473
|
}
|
|
410
474
|
|
|
411
|
-
RCT_EXPORT_METHOD(fetchNativeFrames
|
|
412
|
-
|
|
475
|
+
RCT_EXPORT_METHOD(fetchNativeFrames
|
|
476
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
477
|
+
: (RCTPromiseRejectBlock)reject)
|
|
413
478
|
{
|
|
414
479
|
|
|
415
480
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
@@ -425,79 +490,82 @@ RCT_EXPORT_METHOD(fetchNativeFrames:(RCTPromiseResolveBlock)resolve
|
|
|
425
490
|
NSNumber *frozen = [NSNumber numberWithLong:frames.frozen];
|
|
426
491
|
NSNumber *slow = [NSNumber numberWithLong:frames.slow];
|
|
427
492
|
|
|
428
|
-
resolve(@{
|
|
429
|
-
@"totalFrames": total,
|
|
430
|
-
@"frozenFrames": frozen,
|
|
431
|
-
@"slowFrames": slow,
|
|
493
|
+
resolve(@ {
|
|
494
|
+
@"totalFrames" : total,
|
|
495
|
+
@"frozenFrames" : frozen,
|
|
496
|
+
@"slowFrames" : slow,
|
|
432
497
|
});
|
|
433
498
|
} else {
|
|
434
|
-
|
|
499
|
+
resolve(nil);
|
|
435
500
|
}
|
|
436
501
|
#else
|
|
437
502
|
resolve(nil);
|
|
438
503
|
#endif
|
|
439
504
|
}
|
|
440
505
|
|
|
441
|
-
RCT_EXPORT_METHOD(fetchNativeRelease
|
|
442
|
-
|
|
506
|
+
RCT_EXPORT_METHOD(fetchNativeRelease
|
|
507
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
508
|
+
: (RCTPromiseRejectBlock)reject)
|
|
443
509
|
{
|
|
444
510
|
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
|
|
445
|
-
resolve(@{
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
RCT_EXPORT_METHOD(captureEnvelope
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
511
|
+
resolve(@ {
|
|
512
|
+
@"id" : infoDict[@"CFBundleIdentifier"],
|
|
513
|
+
@"version" : infoDict[@"CFBundleShortVersionString"],
|
|
514
|
+
@"build" : infoDict[@"CFBundleVersion"],
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
RCT_EXPORT_METHOD(captureEnvelope
|
|
519
|
+
: (NSString *_Nonnull)rawBytes options
|
|
520
|
+
: (NSDictionary *_Nonnull)options resolve
|
|
521
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
522
|
+
: (RCTPromiseRejectBlock)reject)
|
|
456
523
|
{
|
|
457
524
|
NSData *data = [[NSData alloc] initWithBase64EncodedString:rawBytes options:0];
|
|
458
525
|
|
|
459
526
|
SentryEnvelope *envelope = [PrivateSentrySDKOnly envelopeWithData:data];
|
|
460
527
|
if (envelope == nil) {
|
|
461
|
-
reject(@"SentryReactNative"
|
|
528
|
+
reject(@"SentryReactNative", @"Failed to parse envelope from byte array.", nil);
|
|
462
529
|
return;
|
|
463
530
|
}
|
|
464
531
|
|
|
465
|
-
|
|
532
|
+
#if DEBUG
|
|
533
|
+
[PrivateSentrySDKOnly captureEnvelope:envelope];
|
|
534
|
+
#else
|
|
535
|
+
if ([[options objectForKey:@"hardCrashed"] boolValue]) {
|
|
536
|
+
// Storing to disk happens asynchronously with captureEnvelope
|
|
537
|
+
[PrivateSentrySDKOnly storeEnvelope:envelope];
|
|
538
|
+
} else {
|
|
466
539
|
[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
|
|
540
|
+
}
|
|
541
|
+
#endif
|
|
475
542
|
resolve(@YES);
|
|
476
543
|
}
|
|
477
544
|
|
|
478
|
-
RCT_EXPORT_METHOD(captureScreenshot
|
|
479
|
-
|
|
545
|
+
RCT_EXPORT_METHOD(captureScreenshot
|
|
546
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
547
|
+
: (RCTPromiseRejectBlock)reject)
|
|
480
548
|
{
|
|
481
549
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
482
|
-
NSArray<NSData
|
|
550
|
+
NSArray<NSData *> *rawScreenshots = [PrivateSentrySDKOnly captureScreenshots];
|
|
483
551
|
NSMutableArray *screenshotsArray = [NSMutableArray arrayWithCapacity:[rawScreenshots count]];
|
|
484
552
|
|
|
485
553
|
int counter = 1;
|
|
486
|
-
for (NSData*
|
|
554
|
+
for (NSData *raw in rawScreenshots) {
|
|
487
555
|
NSMutableArray *screenshot = [NSMutableArray arrayWithCapacity:raw.length];
|
|
488
|
-
const char *bytes = (char*)
|
|
556
|
+
const char *bytes = (char *)[raw bytes];
|
|
489
557
|
for (int i = 0; i < [raw length]; i++) {
|
|
490
558
|
[screenshot addObject:[[NSNumber alloc] initWithChar:bytes[i]]];
|
|
491
559
|
}
|
|
492
560
|
|
|
493
|
-
NSString*
|
|
561
|
+
NSString *filename = @"screenshot.png";
|
|
494
562
|
if (counter > 1) {
|
|
495
563
|
filename = [NSString stringWithFormat:@"screenshot-%d.png", counter];
|
|
496
564
|
}
|
|
497
|
-
[screenshotsArray addObject:@{
|
|
498
|
-
@"data": screenshot,
|
|
499
|
-
@"contentType": @"image/png",
|
|
500
|
-
@"filename": filename,
|
|
565
|
+
[screenshotsArray addObject:@ {
|
|
566
|
+
@"data" : screenshot,
|
|
567
|
+
@"contentType" : @"image/png",
|
|
568
|
+
@"filename" : filename,
|
|
501
569
|
}];
|
|
502
570
|
counter++;
|
|
503
571
|
}
|
|
@@ -508,14 +576,15 @@ RCT_EXPORT_METHOD(captureScreenshot: (RCTPromiseResolveBlock)resolve
|
|
|
508
576
|
#endif
|
|
509
577
|
}
|
|
510
578
|
|
|
511
|
-
RCT_EXPORT_METHOD(fetchViewHierarchy
|
|
512
|
-
|
|
579
|
+
RCT_EXPORT_METHOD(fetchViewHierarchy
|
|
580
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
581
|
+
: (RCTPromiseRejectBlock)reject)
|
|
513
582
|
{
|
|
514
583
|
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
515
|
-
NSData *
|
|
584
|
+
NSData *rawViewHierarchy = [PrivateSentrySDKOnly captureViewHierarchy];
|
|
516
585
|
|
|
517
586
|
NSMutableArray *viewHierarchy = [NSMutableArray arrayWithCapacity:rawViewHierarchy.length];
|
|
518
|
-
const char *bytes = (char*)
|
|
587
|
+
const char *bytes = (char *)[rawViewHierarchy bytes];
|
|
519
588
|
for (int i = 0; i < [rawViewHierarchy length]; i++) {
|
|
520
589
|
[viewHierarchy addObject:[[NSNumber alloc] initWithChar:bytes[i]]];
|
|
521
590
|
}
|
|
@@ -526,16 +595,13 @@ RCT_EXPORT_METHOD(fetchViewHierarchy: (RCTPromiseResolveBlock)resolve
|
|
|
526
595
|
#endif
|
|
527
596
|
}
|
|
528
597
|
|
|
529
|
-
|
|
530
|
-
RCT_EXPORT_METHOD(setUser:(NSDictionary *)userKeys
|
|
531
|
-
otherUserKeys:(NSDictionary *)userDataKeys
|
|
532
|
-
)
|
|
598
|
+
RCT_EXPORT_METHOD(setUser : (NSDictionary *)userKeys otherUserKeys : (NSDictionary *)userDataKeys)
|
|
533
599
|
{
|
|
534
|
-
[SentrySDK configureScope:^(SentryScope *
|
|
600
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
|
|
535
601
|
if (nil == userKeys && nil == userDataKeys) {
|
|
536
602
|
[scope setUser:nil];
|
|
537
603
|
} else {
|
|
538
|
-
SentryUser*
|
|
604
|
+
SentryUser *userInstance = [[SentryUser alloc] init];
|
|
539
605
|
|
|
540
606
|
if (nil != userKeys) {
|
|
541
607
|
[userInstance setUserId:userKeys[@"id"]];
|
|
@@ -554,9 +620,9 @@ RCT_EXPORT_METHOD(setUser:(NSDictionary *)userKeys
|
|
|
554
620
|
}];
|
|
555
621
|
}
|
|
556
622
|
|
|
557
|
-
RCT_EXPORT_METHOD(addBreadcrumb:(NSDictionary *)breadcrumb)
|
|
623
|
+
RCT_EXPORT_METHOD(addBreadcrumb : (NSDictionary *)breadcrumb)
|
|
558
624
|
{
|
|
559
|
-
[SentrySDK configureScope:^(SentryScope *
|
|
625
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
|
|
560
626
|
[scope addBreadcrumb:[RNSentryBreadcrumb from:breadcrumb]];
|
|
561
627
|
}];
|
|
562
628
|
|
|
@@ -565,33 +631,27 @@ RCT_EXPORT_METHOD(addBreadcrumb:(NSDictionary *)breadcrumb)
|
|
|
565
631
|
if (screen != nil) {
|
|
566
632
|
[PrivateSentrySDKOnly setCurrentScreen:screen];
|
|
567
633
|
}
|
|
568
|
-
#endif //SENTRY_HAS_UIKIT
|
|
634
|
+
#endif // SENTRY_HAS_UIKIT
|
|
569
635
|
}
|
|
570
636
|
|
|
571
|
-
RCT_EXPORT_METHOD(clearBreadcrumbs)
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
}];
|
|
637
|
+
RCT_EXPORT_METHOD(clearBreadcrumbs)
|
|
638
|
+
{
|
|
639
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) { [scope clearBreadcrumbs]; }];
|
|
575
640
|
}
|
|
576
641
|
|
|
577
|
-
RCT_EXPORT_METHOD(setExtra:(NSString *)key
|
|
578
|
-
extra:(NSString *)extra
|
|
579
|
-
)
|
|
642
|
+
RCT_EXPORT_METHOD(setExtra : (NSString *)key extra : (NSString *)extra)
|
|
580
643
|
{
|
|
581
|
-
[SentrySDK
|
|
582
|
-
[scope setExtraValue:extra forKey:key];
|
|
583
|
-
}];
|
|
644
|
+
[SentrySDK
|
|
645
|
+
configureScope:^(SentryScope *_Nonnull scope) { [scope setExtraValue:extra forKey:key]; }];
|
|
584
646
|
}
|
|
585
647
|
|
|
586
|
-
RCT_EXPORT_METHOD(setContext:(NSString *)key
|
|
587
|
-
context:(NSDictionary *)context
|
|
588
|
-
)
|
|
648
|
+
RCT_EXPORT_METHOD(setContext : (NSString *)key context : (NSDictionary *)context)
|
|
589
649
|
{
|
|
590
650
|
if (key == nil) {
|
|
591
651
|
return;
|
|
592
652
|
}
|
|
593
653
|
|
|
594
|
-
[SentrySDK configureScope:^(SentryScope *
|
|
654
|
+
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
|
|
595
655
|
if (context == nil) {
|
|
596
656
|
[scope removeContextForKey:key];
|
|
597
657
|
} else {
|
|
@@ -600,25 +660,20 @@ RCT_EXPORT_METHOD(setContext:(NSString *)key
|
|
|
600
660
|
}];
|
|
601
661
|
}
|
|
602
662
|
|
|
603
|
-
RCT_EXPORT_METHOD(setTag:(NSString *)key
|
|
604
|
-
value:(NSString *)value
|
|
605
|
-
)
|
|
663
|
+
RCT_EXPORT_METHOD(setTag : (NSString *)key value : (NSString *)value)
|
|
606
664
|
{
|
|
607
|
-
[SentrySDK
|
|
608
|
-
[scope setTagValue:value forKey:key];
|
|
609
|
-
}];
|
|
665
|
+
[SentrySDK
|
|
666
|
+
configureScope:^(SentryScope *_Nonnull scope) { [scope setTagValue:value forKey:key]; }];
|
|
610
667
|
}
|
|
611
668
|
|
|
612
|
-
RCT_EXPORT_METHOD(crash)
|
|
613
|
-
{
|
|
614
|
-
[SentrySDK crash];
|
|
615
|
-
}
|
|
669
|
+
RCT_EXPORT_METHOD(crash) { [SentrySDK crash]; }
|
|
616
670
|
|
|
617
|
-
RCT_EXPORT_METHOD(closeNativeSdk
|
|
618
|
-
|
|
671
|
+
RCT_EXPORT_METHOD(closeNativeSdk
|
|
672
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
673
|
+
: (RCTPromiseRejectBlock)reject)
|
|
619
674
|
{
|
|
620
|
-
|
|
621
|
-
|
|
675
|
+
[SentrySDK close];
|
|
676
|
+
resolve(@YES);
|
|
622
677
|
}
|
|
623
678
|
|
|
624
679
|
RCT_EXPORT_METHOD(disableNativeFramesTracking)
|
|
@@ -634,70 +689,76 @@ RCT_EXPORT_METHOD(enableNativeFramesTracking)
|
|
|
634
689
|
// the 'tracesSampleRate' or 'tracesSampler' option.
|
|
635
690
|
}
|
|
636
691
|
|
|
637
|
-
RCT_EXPORT_METHOD(captureReplay
|
|
638
|
-
|
|
639
|
-
|
|
692
|
+
RCT_EXPORT_METHOD(captureReplay
|
|
693
|
+
: (BOOL)isHardCrash resolver
|
|
694
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
695
|
+
: (RCTPromiseRejectBlock)reject)
|
|
640
696
|
{
|
|
641
697
|
#if SENTRY_TARGET_REPLAY_SUPPORTED
|
|
642
|
-
|
|
643
|
-
|
|
698
|
+
[PrivateSentrySDKOnly captureReplay];
|
|
699
|
+
resolve([PrivateSentrySDKOnly getReplayId]);
|
|
644
700
|
#else
|
|
645
|
-
|
|
701
|
+
resolve(nil);
|
|
646
702
|
#endif
|
|
647
703
|
}
|
|
648
704
|
|
|
649
705
|
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getCurrentReplayId)
|
|
650
706
|
{
|
|
651
707
|
#if SENTRY_TARGET_REPLAY_SUPPORTED
|
|
652
|
-
|
|
708
|
+
return [PrivateSentrySDKOnly getReplayId];
|
|
653
709
|
#else
|
|
654
|
-
|
|
710
|
+
return nil;
|
|
655
711
|
#endif
|
|
656
712
|
}
|
|
657
713
|
|
|
658
|
-
static NSString*
|
|
659
|
-
static SentryId*
|
|
714
|
+
static NSString *const enabledProfilingMessage = @"Enable Hermes to use Sentry Profiling.";
|
|
715
|
+
static SentryId *nativeProfileTraceId = nil;
|
|
660
716
|
static uint64_t nativeProfileStartTime = 0;
|
|
661
717
|
|
|
662
|
-
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, startProfiling: (BOOL)platformProfilers)
|
|
718
|
+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, startProfiling : (BOOL)platformProfilers)
|
|
663
719
|
{
|
|
664
720
|
#if SENTRY_PROFILING_ENABLED
|
|
665
721
|
try {
|
|
666
722
|
facebook::hermes::HermesRuntime::enableSamplingProfiler();
|
|
667
723
|
if (nativeProfileTraceId == nil && nativeProfileStartTime == 0 && platformProfilers) {
|
|
668
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
724
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
669
725
|
nativeProfileTraceId = [RNSentryId newId];
|
|
670
|
-
nativeProfileStartTime =
|
|
671
|
-
|
|
726
|
+
nativeProfileStartTime =
|
|
727
|
+
[PrivateSentrySDKOnly startProfilerForTrace:nativeProfileTraceId];
|
|
728
|
+
# endif
|
|
672
729
|
} else {
|
|
673
730
|
if (!platformProfilers) {
|
|
674
731
|
NSLog(@"Native profiling is disabled. Only starting Hermes profiling.");
|
|
675
732
|
} else {
|
|
676
|
-
NSLog(@"Native profiling already in progress. Currently existing trace: %@",
|
|
733
|
+
NSLog(@"Native profiling already in progress. Currently existing trace: %@",
|
|
734
|
+
nativeProfileTraceId);
|
|
677
735
|
}
|
|
678
736
|
}
|
|
679
|
-
return @{
|
|
680
|
-
} catch (const std::exception&
|
|
737
|
+
return @{@"started" : @YES};
|
|
738
|
+
} catch (const std::exception &ex) {
|
|
681
739
|
if (nativeProfileTraceId != nil) {
|
|
682
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
683
|
-
[PrivateSentrySDKOnly discardProfilerForTrace:
|
|
684
|
-
#endif
|
|
740
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
741
|
+
[PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
|
|
742
|
+
# endif
|
|
685
743
|
nativeProfileTraceId = nil;
|
|
686
744
|
}
|
|
687
745
|
nativeProfileStartTime = 0;
|
|
688
|
-
return @{
|
|
746
|
+
return @ {
|
|
747
|
+
@"error" : [NSString stringWithCString:ex.what()
|
|
748
|
+
encoding:[NSString defaultCStringEncoding]]
|
|
749
|
+
};
|
|
689
750
|
} catch (...) {
|
|
690
751
|
if (nativeProfileTraceId != nil) {
|
|
691
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
692
|
-
[PrivateSentrySDKOnly discardProfilerForTrace:
|
|
693
|
-
#endif
|
|
752
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
753
|
+
[PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
|
|
754
|
+
# endif
|
|
694
755
|
nativeProfileTraceId = nil;
|
|
695
756
|
}
|
|
696
757
|
nativeProfileStartTime = 0;
|
|
697
|
-
return @{ @"error": @"Failed to start profiling" };
|
|
758
|
+
return @ { @"error" : @"Failed to start profiling" };
|
|
698
759
|
}
|
|
699
760
|
#else
|
|
700
|
-
return @{ @"error": enabledProfilingMessage };
|
|
761
|
+
return @ { @"error" : enabledProfilingMessage };
|
|
701
762
|
#endif
|
|
702
763
|
}
|
|
703
764
|
|
|
@@ -705,12 +766,14 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, stopProfiling)
|
|
|
705
766
|
{
|
|
706
767
|
#if SENTRY_PROFILING_ENABLED
|
|
707
768
|
try {
|
|
708
|
-
NSDictionary<NSString *, id> *
|
|
769
|
+
NSDictionary<NSString *, id> *nativeProfile = nil;
|
|
709
770
|
if (nativeProfileTraceId != nil && nativeProfileStartTime != 0) {
|
|
710
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
771
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
711
772
|
uint64_t nativeProfileStopTime = clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
|
|
712
|
-
nativeProfile = [PrivateSentrySDKOnly collectProfileBetween:nativeProfileStartTime
|
|
713
|
-
|
|
773
|
+
nativeProfile = [PrivateSentrySDKOnly collectProfileBetween:nativeProfileStartTime
|
|
774
|
+
and:nativeProfileStopTime
|
|
775
|
+
forTrace:nativeProfileTraceId];
|
|
776
|
+
# endif
|
|
714
777
|
}
|
|
715
778
|
// Cleanup native profiles
|
|
716
779
|
nativeProfileTraceId = nil;
|
|
@@ -722,57 +785,66 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, stopProfiling)
|
|
|
722
785
|
facebook::hermes::HermesRuntime::dumpSampledTraceToStream(ss);
|
|
723
786
|
|
|
724
787
|
std::string s = ss.str();
|
|
725
|
-
NSString *data = [NSString stringWithCString:s.c_str()
|
|
788
|
+
NSString *data = [NSString stringWithCString:s.c_str()
|
|
789
|
+
encoding:[NSString defaultCStringEncoding]];
|
|
726
790
|
|
|
727
|
-
#if SENTRY_PROFILING_DEBUG_ENABLED
|
|
791
|
+
# if SENTRY_PROFILING_DEBUG_ENABLED
|
|
728
792
|
NSString *rawProfileFileName = @"hermes.profile";
|
|
729
793
|
NSError *error = nil;
|
|
730
|
-
NSString *rawProfileFilePath =
|
|
731
|
-
|
|
794
|
+
NSString *rawProfileFilePath =
|
|
795
|
+
[NSTemporaryDirectory() stringByAppendingPathComponent:rawProfileFileName];
|
|
796
|
+
if (![data writeToFile:rawProfileFilePath
|
|
797
|
+
atomically:YES
|
|
798
|
+
encoding:NSUTF8StringEncoding
|
|
799
|
+
error:&error]) {
|
|
732
800
|
NSLog(@"Error writing Raw Hermes Profile to %@: %@", rawProfileFilePath, error);
|
|
733
801
|
} else {
|
|
734
802
|
NSLog(@"Raw Hermes Profile saved to %@", rawProfileFilePath);
|
|
735
803
|
}
|
|
736
|
-
#endif
|
|
804
|
+
# endif
|
|
737
805
|
|
|
738
806
|
if (data == nil) {
|
|
739
|
-
|
|
807
|
+
return @ { @"error" : @"Failed to retrieve Hermes profile." };
|
|
740
808
|
}
|
|
741
809
|
|
|
742
810
|
if (nativeProfile == nil) {
|
|
743
|
-
|
|
811
|
+
return @ { @"profile" : data };
|
|
744
812
|
}
|
|
745
813
|
|
|
746
|
-
return @{
|
|
747
|
-
|
|
748
|
-
|
|
814
|
+
return @ {
|
|
815
|
+
@"profile" : data,
|
|
816
|
+
@"nativeProfile" : nativeProfile,
|
|
749
817
|
};
|
|
750
|
-
} catch (const std::exception&
|
|
818
|
+
} catch (const std::exception &ex) {
|
|
751
819
|
if (nativeProfileTraceId != nil) {
|
|
752
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
753
|
-
|
|
754
|
-
#endif
|
|
755
|
-
|
|
820
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
821
|
+
[PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
|
|
822
|
+
# endif
|
|
823
|
+
nativeProfileTraceId = nil;
|
|
756
824
|
}
|
|
757
825
|
nativeProfileStartTime = 0;
|
|
758
|
-
return @{
|
|
826
|
+
return @ {
|
|
827
|
+
@"error" : [NSString stringWithCString:ex.what()
|
|
828
|
+
encoding:[NSString defaultCStringEncoding]]
|
|
829
|
+
};
|
|
759
830
|
} catch (...) {
|
|
760
831
|
if (nativeProfileTraceId != nil) {
|
|
761
|
-
#if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
762
|
-
|
|
763
|
-
#endif
|
|
764
|
-
|
|
832
|
+
# if SENTRY_TARGET_PROFILING_SUPPORTED
|
|
833
|
+
[PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
|
|
834
|
+
# endif
|
|
835
|
+
nativeProfileTraceId = nil;
|
|
765
836
|
}
|
|
766
837
|
nativeProfileStartTime = 0;
|
|
767
|
-
return @{ @"error": @"Failed to stop profiling" };
|
|
838
|
+
return @ { @"error" : @"Failed to stop profiling" };
|
|
768
839
|
}
|
|
769
840
|
#else
|
|
770
|
-
return @{ @"error": enabledProfilingMessage };
|
|
841
|
+
return @ { @"error" : enabledProfilingMessage };
|
|
771
842
|
#endif
|
|
772
843
|
}
|
|
773
844
|
|
|
774
|
-
RCT_EXPORT_METHOD(crashedLastRun
|
|
775
|
-
|
|
845
|
+
RCT_EXPORT_METHOD(crashedLastRun
|
|
846
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
847
|
+
: (RCTPromiseRejectBlock)reject)
|
|
776
848
|
{
|
|
777
849
|
resolve(@([SentrySDK crashedLastRun]));
|
|
778
850
|
}
|
|
@@ -786,4 +858,11 @@ RCT_EXPORT_METHOD(crashedLastRun:(RCTPromiseResolveBlock)resolve
|
|
|
786
858
|
}
|
|
787
859
|
#endif
|
|
788
860
|
|
|
861
|
+
RCT_EXPORT_METHOD(getNewScreenTimeToDisplay
|
|
862
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
863
|
+
: (RCTPromiseRejectBlock)reject)
|
|
864
|
+
{
|
|
865
|
+
[_timeToDisplay getTimeToDisplay:resolve];
|
|
866
|
+
}
|
|
867
|
+
|
|
789
868
|
@end
|