Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable Native SDK initialization from React Native and use an existing instance #1248

Closed
5 of 9 tasks
pioneer32 opened this issue Dec 17, 2020 · 4 comments
Closed
5 of 9 tasks
Assignees

Comments

@pioneer32
Copy link

Platform:

  • iOS
  • Android

SDK:

  • @sentry/react-native (>= 1.0.0)
  • sentry-cocoa (6.0.9)
  • react-native-sentry (<= 0.43.2)

SDK version:

  • @sentry/react-native 2.1.0
  • sentry-cocoa 6.0.9

react-native version: 0.60.5 (also tried to upgrade to 0.62.2 - the same outcome as with 0.60.5)

Are you using Expo?

  • Yes
  • No

Are you using sentry.io or on-premise?

  • sentry.io (SaaS)
  • on-premise

If you are using sentry.io, please post a link to your issue so we can take a look:

When the native one is initialised first and JS one is the second:
https://sentry.io/organizations/vladislav-churakov/issues/2096897776/?project=1834395&query=is%3Aunresolved

When no native one is used, one JS one:
https://sentry.io/organizations/vladislav-churakov/issues/2094670206/?project=1834395&query=is%3Aunresolved

Configuration:

(@sentry/react-native)

      Sentry.init({
        dsn: 'https://....ingest.sentry.io/...'
        environment: Config.RELEASE_TYPE, // a string that can only be "test" "preprod" "production"
        debug: true, // Changing this has no effect on what we see in Sentry
      });

(sentry-cocoa in AppDelegate.swift)

  func application( ... didFinishLaunchingWithOptions ... ) -> Bool {
      SentrySDK.start { options in
        options.dsn = "https://....ingest.sentry.io/..."
        options.environment = SettingsHelper.sharedInstance.releaseType // a string that can only be "test" "preprod" "production"
        options.debug = true // Changing this has no effect on what we see in Sentry
      }


I have following issue:

Given there's an iOS native app that uses sentry-cocoa and all the native stacktraces are nicely symbolised with some functionality done with react-native (a "hybrid" app).

When SentrySDK.start is called in AppDelegate.swift the first (we need this as we need to see native crashes) and then Sentry.init is called in JS as react-native starts , the JS stacktrace looks very bad in Sentry:

image

Obviously, there can not be an attempt to process it with JS sourcemaps.

However, when the native SentrySDK.start is disabled, and we only call Sentry.init in JS, the same JS error stacktrace looks way better:

image

Thought sourcemaps weren't applied in this case (just because there hadn't been uploaded), there was an attempt to process this stacktrace, and this definitely looks like a usual JS issue in Sentry

Steps to reproduce:

  • Have a native up with sentry-cocoa integration. SentrySDK.start is called in AppDelegate
  • Add react-native into this app
  • Remove sentry-cocoa from Pods
  • Add @sentry/react-native into this project (now sentry-cocoa is added again)
  • Add calling Sentry.init in JS
  • Throw a JS error

Actual result:

  • No nice JS stacktraces processed with sourcemaps.
  • Native ones are symbolised

Expected result:

  • JS errors are processed with sourcemaps
  • Native ones are symbolised
@jennmueng
Copy link
Member

You actually don't need to call SentrySDK.start a second time to capture native crashes, the React Native SDK already initializes the native SDK for you. This should work for most cases.

Otherwise, if you need to specify your own options on the native layer or need to use SentrySDK.start, you can pass enableNative: false to the options on the JS React Native side. This might be some side effects if you choose to do this, so you should create a beforeSend that replicates what the React Native SDK sets in these lines to not have events sent twice:

if (nil != event.exceptions.firstObject.type &&
[event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location != NSNotFound) {
NSLog(@"Unhandled JS Exception");
return nil;
}

@pioneer32
Copy link
Author

@jennmueng Thank you very much for your response.

Our app is primarily a native app, in which some functionality is implemented with react-native. So, a lot happens before before JS (react-native) starts. I know, under the hood, @sentry/react-native calls SentrySDK.start, which we could've used if that hadn't been too late for us. Therefore, we need to keep calling SentrySDK.start in AppDelegate as this is how we catch the native crashes before JS (react-native) starts.

Ideally, what we expect to have is: when JSCRuntime starts and Sentry.init is called from JS, it reuses the existing native Senty client to send nice JS stacktraces, the breadcrumbs from the native code are properly combined with JS ones into the correct sequence.

How I approached that:

  • Knowing that @sentry/react-native is built on top of cocoa-sentry, I added @sentry/react-native and removed cocoa-sentry from Podfile, because this pod is now provided via react-native autolinking.

The project compiled and the native crashes kept captured the way they used to be caught and symbolised. That was cool and easy. Then I approached the JS side:

I added calling Sentry.init to index.ts. The result was: native crashes remained nice and symbolised, but no breadcrums added via JS were available and JS crashes were processed as native ones and looked like this:
image

The following combinations give same outcome:

  • Calling SentrySDK.start in AppDelegate first and not calling Sentry.init in JS
  • Calling SentrySDK.start in AppDelegate first and calling Sentry.init with enableNative:false in JS

The only way to get Sentry to process JS stacktraces nicely and have breadcrumbs that are added via JS available is to completely disable calling SentrySDK.start in AppDelegate, which isn't an option for us at all.

With any combination, I've never had any event duplicated.

How can I get @sentry/react-native to use an existing and already initialised native Sentry client and have JS breadcrumbs and nice JS stacktraces?

TIA

@jennmueng
Copy link
Member

Hmm there's currently no way to have the React Native SDK not initialize the native SDK and use an existing one. I'm adding this to our TODO.

@jennmueng jennmueng self-assigned this Dec 22, 2020
@jennmueng jennmueng changed the title Integrating react-native into a native app - JS Stacktrace isn't processed Disable Native SDK initialization from React Native and use an existing instance Dec 22, 2020
@jennmueng
Copy link
Member

Closing as the PR introducing feature has been merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants