Sentry-react-native: Doesn't Catch Native Exceptions before the Javascript Runs

Created on 7 Feb 2019  ·  16Comments  ·  Source: getsentry/sentry-react-native

OS:

  • [ ] Windows
  • [x] MacOS
  • [ ] Linux

_Platform:_

  • [ ] iOS
  • [x] Android

Output of node -v && npm -v && npm ls --prod --depth=0

v10.8.0
6.7.0
[email protected] /Users/hhff/dev/light-two/LightOS
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── UNMET PEER DEPENDENCY [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected] invalid
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected] invalid
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

npm ERR! peer dep missing: react-native@^0.51.0, required by [email protected]
npm ERR! peer dep missing: react-native@^0.51, required by [email protected]
npm ERR! invalid: [email protected] /Users/hhff/dev/light-two/LightOS/node_modules/react-native-fs
npm ERR! extraneous: [email protected] /Users/hhff/dev/light-two/LightOS/node_modules/base-64
npm ERR! extraneous: [email protected] /Users/hhff/dev/light-two/LightOS/node_modules/utf8
npm ERR! invalid: [email protected] /Users/hhff/dev/light-two/LightOS/node_modules/react-native-telephony

Config:

Sentry.config('https://[email protected]/...', {
....
}).install()

I have following issue:

I'd like to use Sentry to capture information in early Android hooks like MainActivity#onCreate. Unfortunately, because this lib requires the JS to initialize the Native client over the bridge, those early hooks will no-op because it hasn't initialized yet.

Steps to reproduce:

  • Use this Lib
  • Add Sentry.capture("Hello!") to MainActivity#onCreate

Actual result:

  • The message doesn't make it to Sentry

Expected result:

  • The message should make it to Sentry

FWIW, my current work around is to init the client early in the MainApplication#onCreate. Then my JS runs, and re-inits the Sentry client through the Native Module API. Seems OK, but not ideal!

Thanks for all the hard work!

Feature Request iOMac Android 🦔react-native-sentry

Most helpful comment

We're planning to tackle this soon. Sorry for the delay

All 16 comments

Yeah, this is correct.
The problem is that we need the DSN from JS in order to init the SDK on the native side.
So I am not sure if we are ever able to fix this.

I was thinking that the DSN could be a native variable rather than a JS string, and that var could be passed back to the JS side if necessary as a const (React Native supports constants over the bridge).

IMO if your app is crashing from native exceptions before the JS runs, but not reporting them to Sentry, thats a big deal!

Is there any problem with the approach above? ie - instantiating the native client twice? Kinda feels like something this lib should do by default.

That could be an approach we could take, problem with this is where to set the DSN natively?!

I'll also be honest with you, this will probably not be changed in the near future.
We are currently discussing rewriting the whole SDK to be unified with our other SDKs https://github.com/getsentry/sentry-javascript

but it's not been decided yet. If we do, we'll think about how to handle this properly.

But in general I agree with what you are saying (how it should/could work).

Understood, thank you.

One last Q - Is there any problem with the approach above? ie - instantiating the native client twice?

Just wanna be sure that’s not going to cause some type of collision, etc.

Hi @HazAT
Can you maybe expose the Sentry-Android dependency so on Android we can instantiate Sentry before React Native is loaded?

// file: @sentry/react-native/android/build.gradle
dependencies {
    implementation 'com.facebook.react:react-native:+'
-   implementation 'io.sentry:sentry-android:1.7.23'
+   api 'io.sentry:sentry-android:1.7.23'
}

Then in our Android MainApplication.java we can do:

Sentry.init(sentryConfig.dsn, AndroidSentryClientFactory(applicationContext))

We are using @sentry/react-native v 1.0.5

Any update on this?

I am using

io.sentry:sentry-android-core:2.1.3
io.sentry:sentry-android-ndk:2.1.3
io.sentry:sentry-android:2.1.3

And faced with this problem. Sometimes an app crashes within java or binary code before js initialization.

I moved initialization to native level by adding the following:

AndroidManifest.xml
(inside application tag)

        <meta-data android:name="io.sentry.dsn" android:value="${SENTRY_DSN}" />
        <meta-data android:name="io.sentry.auto-init" android:value="true" tools:node="replace"/>
        <meta-data android:name="io.sentry.ndk.enable" android:value="true" />

in app/build.gradle

 defaultConfig {
        manifestPlaceholders = [
                SENTRY_DSN: "https://..."
        ]
     //....
   }

it is catching java errors even from Application::onCreate method.

I still keep init in js

Sentry.init({
  enabled: true,
  enableAutoSessionTracking: true,
  dsn: SENTRY_DSN,
});

which is probably initializing sdk second time. But looks like it's working fine.

Will post updates.

@punksta Any updates on this? Did you stumble upon any issues when using this approach of initializing the SDK twice?

@thesagarshakya I haven't noticed any major issues. The only issue I noticed is crashes from binary(c++) code are not linked to a release in the dashboard, but I guess it's a different issue.

@HazAT Any updates on this? Another 1 year have gone by..

We've been discussing possible solutions internally, this is a pretty complex and difficult issue and if we find a good solution we'll make it happen. But for now as a workaround you can initialize the SDKs twice, by this I mean calling .init on the Andrid/Cocoa SDK in your own code and it should work fine.

We're planning to tackle this soon. Sorry for the delay

With this PR https://github.com/getsentry/sentry-react-native/pull/1259 merged, it's possible now to catch native errors before the JS code runs. You would have to manually initialize the SDK on the native layer yourself, and pass shouldInitializeNativeSdk: false to the options in JS.

@jennmueng do you know how the RN engine gets started on Android? is it thru ContentProvider?

wondering if https://github.com/getsentry/sentry-dart/issues/265#issuecomment-755937692 is also an issue for RN

I'm not fully sure myself as I've not really worked with it, but I think it should started from the Application class.

yeah just looked up inside of an old demo, RN creates an Application class that hosts a ReactNativeHost.
Also, MainActivity gets created extending a ReactActivity, so all the magic is happening there + native libs being loaded by SoLoader which is also a Facebook lib.

so yeah a few things could be caught by the SDK, but RN also has ContentProvider, See this https://github.com/facebook/react-native/blob/6e6443afd04a847ef23fb6254a84e48c70b45896/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobProvider.java

so what I've guessed is partly true.

Was this page helpful?
0 / 5 - 0 ratings