2525#import < Sentry/SentryEvent.h>
2626#import < Sentry/SentryException.h>
2727#import < Sentry/SentryFormatter.h>
28- #import < Sentry/SentryOptions.h>
29- #import < Sentry/SentryOptionsInternal.h>
3028#import < Sentry/SentryUser.h>
3129
3230// This guard prevents importing Hermes in JSC apps
@@ -84,24 +82,68 @@ - (instancetype)init
8482 return self;
8583}
8684
85+ - (NSMutableDictionary *)prepareOptions : (NSDictionary *)options
86+ {
87+ SentryBeforeSendEventCallback beforeSend = ^SentryEvent *(SentryEvent *event) {
88+ // We don't want to send an event after startup that came from a Unhandled JS Exception of
89+ // React Native because we sent it already before the app crashed.
90+ if (nil != event.exceptions .firstObject .type &&
91+ [event.exceptions.firstObject.type rangeOfString: @" Unhandled JS Exception" ].location
92+ != NSNotFound ) {
93+ return nil ;
94+ }
95+
96+ // Regex and Str are set when one of them has value so we only need to check one of them.
97+ if (self->_ignoreErrorPatternsStr || self->_ignoreErrorPatternsRegex ) {
98+ for (SentryException *exception in event.exceptions ) {
99+ if ([self shouldIgnoreError: exception.value]) {
100+ return nil ;
101+ }
102+ }
103+ if ([self shouldIgnoreError: event.message.message]) {
104+ return nil ;
105+ }
106+ }
107+
108+ [self setEventOriginTag: event];
109+ return event;
110+ };
111+
112+ NSMutableDictionary *mutableOptions = [options mutableCopy ];
113+ [mutableOptions setValue: beforeSend forKey: @" beforeSend" ];
114+
115+ // remove performance traces sample rate and traces sampler since we don't want to synchronize
116+ // these configurations to the Native SDKs. The user could tho initialize the SDK manually and
117+ // set themselves.
118+ [mutableOptions removeObjectForKey: @" tracesSampleRate" ];
119+ [mutableOptions removeObjectForKey: @" tracesSampler" ];
120+ [mutableOptions removeObjectForKey: @" enableTracing" ];
121+
122+ [self trySetIgnoreErrors: mutableOptions];
123+
124+ return mutableOptions;
125+ }
126+
87127RCT_EXPORT_MODULE ()
88128RCT_EXPORT_METHOD(initNativeSdk : (NSDictionary *_Nonnull)options resolve : (
89129 RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject)
90130{
131+ NSMutableDictionary *mutableOptions = [self prepareOptions: options];
132+ #if SENTRY_TARGET_REPLAY_SUPPORTED
133+ BOOL isSessionReplayEnabled = [RNSentryReplay updateOptions: mutableOptions];
134+ #else
135+ // Defaulting to false for unsupported targets
136+ BOOL isSessionReplayEnabled = NO ;
137+ #endif
91138 NSError *error = nil ;
92- SentryOptions *sentryOptions = [self createOptionsWithDictionary: options error: &error];
139+ [SentrySDKWrapper setupWithDictionary: mutableOptions
140+ isSessionReplayEnabled: isSessionReplayEnabled
141+ error: &error];
93142 if (error != nil ) {
94143 reject (@" SentryReactNative" , error.localizedDescription , error);
95144 return ;
96145 }
97146
98- NSString *sdkVersion = [PrivateSentrySDKOnly getSdkVersionString ];
99- [PrivateSentrySDKOnly setSdkName: NATIVE_SDK_NAME andVersionString: sdkVersion];
100- [PrivateSentrySDKOnly addSdkPackage: REACT_NATIVE_SDK_PACKAGE_NAME
101- version: REACT_NATIVE_SDK_PACKAGE_VERSION];
102-
103- [SentrySDKWrapper startWithOptions: sentryOptions];
104-
105147#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
106148 BOOL appIsActive =
107149 [[UIApplication sharedApplication ] applicationState ] == UIApplicationStateActive;
@@ -112,8 +154,8 @@ - (instancetype)init
112154 // If the app is active/in foreground, and we have not sent the SentryHybridSdkDidBecomeActive
113155 // notification, send it.
114156 if (appIsActive && !sentHybridSdkDidBecomeActive
115- && (PrivateSentrySDKOnly. options . enableAutoSessionTracking
116- || PrivateSentrySDKOnly. options . enableWatchdogTerminationTracking )) {
157+ && ([SentrySDKWrapper enableAutoSessionTracking ] ||
158+ [SentrySDKWrapper enableWatchdogTerminationTracking ] )) {
117159 [[NSNotificationCenter defaultCenter ] postNotificationName: @" SentryHybridSdkDidBecomeActive"
118160 object: nil ];
119161
@@ -127,7 +169,7 @@ - (instancetype)init
127169 resolve (@YES );
128170}
129171
130- - (void )trySetIgnoreErrors : (NSMutableDictionary *)options
172+ - (void )trySetIgnoreErrors : (NSDictionary *)options
131173{
132174 NSArray *ignoreErrorsStr = nil ;
133175 NSArray *ignoreErrorsRegex = nil ;
@@ -193,136 +235,6 @@ - (BOOL)shouldIgnoreError:(NSString *)message
193235 return NO ;
194236}
195237
196- - (SentryOptions *_Nullable)createOptionsWithDictionary : (NSDictionary *_Nonnull)options
197- error : (NSError *_Nonnull *_Nonnull)errorPointer
198- {
199- SentryBeforeSendEventCallback beforeSend = ^SentryEvent *(SentryEvent *event) {
200- // We don't want to send an event after startup that came from a Unhandled JS Exception of
201- // React Native because we sent it already before the app crashed.
202- if (nil != event.exceptions .firstObject .type &&
203- [event.exceptions.firstObject.type rangeOfString: @" Unhandled JS Exception" ].location
204- != NSNotFound ) {
205- return nil ;
206- }
207-
208- // Regex and Str are set when one of them has value so we only need to check one of them.
209- if (self->_ignoreErrorPatternsStr || self->_ignoreErrorPatternsRegex ) {
210- for (SentryException *exception in event.exceptions ) {
211- if ([self shouldIgnoreError: exception.value]) {
212- return nil ;
213- }
214- }
215- if ([self shouldIgnoreError: event.message.message]) {
216- return nil ;
217- }
218- }
219-
220- [self setEventOriginTag: event];
221- return event;
222- };
223-
224- NSMutableDictionary *mutableOptions = [options mutableCopy ];
225- [mutableOptions setValue: beforeSend forKey: @" beforeSend" ];
226-
227- // remove performance traces sample rate and traces sampler since we don't want to synchronize
228- // these configurations to the Native SDKs. The user could tho initialize the SDK manually and
229- // set themselves.
230- [mutableOptions removeObjectForKey: @" tracesSampleRate" ];
231- [mutableOptions removeObjectForKey: @" tracesSampler" ];
232- [mutableOptions removeObjectForKey: @" enableTracing" ];
233-
234- #if SENTRY_TARGET_REPLAY_SUPPORTED
235- [RNSentryReplay updateOptions: mutableOptions];
236- #endif
237-
238- SentryOptions *sentryOptions = [SentryOptionsInternal initWithDict: mutableOptions
239- didFailWithError: errorPointer];
240- if (*errorPointer != nil ) {
241- return nil ;
242- }
243-
244- // Exclude Dev Server and Sentry Dsn request from Breadcrumbs
245- NSString *dsn = [self getURLFromDSN: [mutableOptions valueForKey: @" dsn" ]];
246- NSString *devServerUrl = [mutableOptions valueForKey: @" devServerUrl" ];
247- sentryOptions.beforeBreadcrumb
248- = ^SentryBreadcrumb *_Nullable (SentryBreadcrumb *_Nonnull breadcrumb)
249- {
250- NSString *url = breadcrumb.data [@" url" ] ?: @" " ;
251-
252- if ([@" http" isEqualToString: breadcrumb.type]
253- && ((dsn != nil && [url hasPrefix: dsn])
254- || (devServerUrl != nil && [url hasPrefix: devServerUrl]))) {
255- return nil ;
256- }
257- return breadcrumb;
258- };
259-
260- if ([mutableOptions valueForKey: @" enableNativeCrashHandling" ] != nil ) {
261- BOOL enableNativeCrashHandling = [mutableOptions[@" enableNativeCrashHandling" ] boolValue ];
262-
263- if (!enableNativeCrashHandling) {
264- sentryOptions.enableCrashHandler = NO ;
265- }
266- }
267-
268- // Set spotlight option
269- if ([mutableOptions valueForKey: @" spotlight" ] != nil ) {
270- id spotlightValue = [mutableOptions valueForKey: @" spotlight" ];
271- if ([spotlightValue isKindOfClass: [NSString class ]]) {
272- NSLog (@" Using Spotlight on address: %@ " , spotlightValue);
273- sentryOptions.enableSpotlight = true ;
274- sentryOptions.spotlightUrl = spotlightValue;
275- } else if ([spotlightValue isKindOfClass: [NSNumber class ]]) {
276- sentryOptions.enableSpotlight = [spotlightValue boolValue ];
277- id defaultSpotlightUrl = [mutableOptions valueForKey: @" defaultSidecarUrl" ];
278- if (defaultSpotlightUrl != nil ) {
279- sentryOptions.spotlightUrl = defaultSpotlightUrl;
280- }
281- }
282- }
283-
284- if ([mutableOptions valueForKey: @" enableLogs" ] != nil ) {
285- id enableLogsValue = [mutableOptions valueForKey: @" enableLogs" ];
286- if ([enableLogsValue isKindOfClass: [NSNumber class ]]) {
287- [RNSentryExperimentalOptions setEnableLogs: [enableLogsValue boolValue ]
288- sentryOptions: sentryOptions];
289- }
290- }
291- [self trySetIgnoreErrors: mutableOptions];
292-
293- // Enable the App start and Frames tracking measurements
294- if ([mutableOptions valueForKey: @" enableAutoPerformanceTracing" ] != nil ) {
295- BOOL enableAutoPerformanceTracing =
296- [mutableOptions[@" enableAutoPerformanceTracing" ] boolValue ];
297- PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = enableAutoPerformanceTracing;
298- #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
299- PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = enableAutoPerformanceTracing;
300- #endif
301- }
302-
303- // Failed requests can only be enabled in one SDK to avoid duplicates
304- sentryOptions.enableCaptureFailedRequests = NO ;
305-
306- NSDictionary *experiments = options[@" _experiments" ];
307- if (experiments != nil && [experiments isKindOfClass: [NSDictionary class ]]) {
308- BOOL enableUnhandledCPPExceptions =
309- [experiments[@" enableUnhandledCPPExceptionsV2" ] boolValue ];
310- [RNSentryExperimentalOptions setEnableUnhandledCPPExceptionsV2: enableUnhandledCPPExceptions
311- sentryOptions: sentryOptions];
312- }
313-
314- return sentryOptions;
315- }
316-
317- - (NSString *_Nullable)getURLFromDSN : (NSString *)dsn
318- {
319- NSURL *url = [NSURL URLWithString: dsn];
320- if (!url) {
321- return nil ;
322- }
323- return [NSString stringWithFormat: @" %@ ://%@ " , url.scheme, url.host];
324- }
325-
326238- (void )setEventOriginTag : (SentryEvent *)event
327239{
328240 if (event.sdk != nil ) {
@@ -451,7 +363,7 @@ - (void)stopObserving
451363 contexts[@" os" ] = os;
452364 }
453365
454- NSString *releaseName = SentrySDKInternal. options . releaseName ;
366+ NSString *releaseName = [SentrySDKWrapper releaseName ] ;
455367 if (releaseName) {
456368 contexts[@" release" ] = releaseName;
457369 }
@@ -483,7 +395,7 @@ - (void)stopObserving
483395RCT_EXPORT_METHOD (fetchNativeDeviceContexts : (RCTPromiseResolveBlock)resolve rejecter : (
484396 RCTPromiseRejectBlock)reject)
485397{
486- if (PrivateSentrySDKOnly. options . debug ) {
398+ if ([SentrySDKWrapper debug ] ) {
487399 NSLog (@" Bridge call to: deviceContexts" );
488400 }
489401 __block NSMutableDictionary <NSString *, id > *serializedScope;
@@ -498,7 +410,7 @@ - (void)stopObserving
498410 forKey: @" user" ];
499411 }
500412
501- if (PrivateSentrySDKOnly. options . debug ) {
413+ if ([SentrySDKWrapper debug ] ) {
502414 NSData *data = [NSJSONSerialization dataWithJSONObject: serializedScope
503415 options: 0
504416 error: nil ];
0 commit comments