react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

[🐛] 🔥 Crashlytics - non-fatal issues are nameless in the crashlytics dashboard for android

Open PetterKnudsen98 opened this issue 4 years ago • 9 comments
trafficstars

Issue

Non-fatal issues in the crashlytics dashboard are simply shown as '.java' for android in production even when supplying recordError with a second parameter. Works as expected for IOS in prod, as well as android in dev.

image

Part of the code recording non-fatal errors:

 const errorMessage = `[${String(severity).toUpperCase()}] ${message}`;

crashlytics()
   .setUserId(SessionStore.sessionId)
   .then(() =>
      crashlytics()
        .setAttributes(keys ?? {})
        .then(() => crashlytics().recordError(err, errorMessage)),
);

I have tested a bit with obsfuscation, and it seems thats the problem. I have yet to find a solution to this problem though.


Project Files

Javascript

Click To Expand

package.json:

    "@react-native-firebase/analytics": "^12.6.0",
    "@react-native-firebase/app": "^12.6.0",
    "@react-native-firebase/crashlytics": "^12.6.0",
    "@react-native-firebase/messaging": "^12.6.0",

firebase.json for react-native-firebase v6:

 "react-native": {
    "crashlytics_auto_collection_enabled": false,
    "crashlytics_debug_enabled": false,
    "analytics_auto_collection_enabled": false
  }

iOS

Click To Expand

ios/Podfile:

  • [ ] I'm not using Pods
  • [x] I'm using Pods and my Podfile looks like:
# N/A

AppDelegate.m:

// N/A

Android

Click To Expand

Have you converted to AndroidX?

  • [x] my application is an AndroidX application?
  • [ ] I am using android/gradle.settings jetifier=true for Android compatibility?
  • [ ] I am using the NPM package jetifier for react-native compatibility?

android/build.gradle:

// N/A

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<!-- N/A -->

Environment

Click To Expand

react-native info output:

 System:
    OS: Windows 10 10.0.19043
    CPU: (16) x64 AMD Ryzen 7 1700 Eight-Core Processor
    Memory: 27.77 GB / 47.94 GB
  Binaries:
    Node: 12.15.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.4 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 7.20.6 - 
    Watchman: Not Found
  SDKs:
    Android SDK: Not Found
    Windows SDK: Not Found
  IDEs:
    Android Studio: Version  4.2.0.0 AI-202.7660.26.42.7351085
    Visual Studio: 16.11.31613.86 (Visual Studio Professional 2019)
  Languages:
    Java: 1.8.0_181
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2
    react-native: ^0.64.2 => 0.64.2
    react-native-windows: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

  • Platform that you're experiencing the issue on:
    • [ ] iOS
    • [x] Android
    • [ ] iOS but have not tested behavior on Android
    • [ ] Android but have not tested behavior on iOS
    • [ ] Both
  • react-native-firebase version you're using that has this issue:
    • 12.6
  • Firebase module(s) you're using that has the issue:
    • Crashlytics
  • Are you using TypeScript?
    • Y & 4.3.5

PetterKnudsen98 avatar Aug 25 '21 13:08 PetterKnudsen98

Hermes or no? Looks like this #5849 but you have advanced the conversation by adding the information about testing obfuscation or not. Obfuscation at what level though, bundle or java or both? Not sure what we can do here but I'm interested in any more information you can provide. Versions of react-native and react-native-firebase are all out of date. You skipped all the android stuff so I'm unsure on the toolchain there but I'm most interested in gradle 7.3 / gradle plugin 7.0.3 / JDK11 (current) to make sure we're not chasing ghosts

mikehardy avatar Nov 17 '21 11:11 mikehardy

Hermes or no?

Yes, we are using hermes.

Obfuscation at what level though, bundle or java or both?

I will admit I don't know too much about obsfuscation in android, but minifyEnabled is set to true in app\build.gradle. We have a proguard file but I never managed to tweak it to fix the issue. I confirmed that setting minifyEnabled to false resolved the issue, but I didn't feel that doing so was a proper fix.

Versions of react-native and react-native-firebase are all out of date.

I update these on the regular, we are currently on:

    "react-native": "^0.66.1",
    "@react-native-firebase/analytics": "^13.0.0",
    "@react-native-firebase/app": "^13.0.0",
    "@react-native-firebase/crashlytics": "^13.0.0",
    "@react-native-firebase/messaging": "^13.0.0",

You skipped all the android stuff so I'm unsure on the toolchain there but I'm most interested in gradle 7.3 / gradle plugin 7.0.3 / JDK11 (current) to make sure we're not chasing ghosts

Sorry about that, we're using gradle 6.9, android gradlew plugin version 4.2.2 and jdk is 11.0.10.

PetterKnudsen98 avatar Nov 17 '21 12:11 PetterKnudsen98

Hmm toolchain checks out - yes you are quite up to date now except perhaps the gradle-y things but those probably won't have bearing. minifyEnabled is native level code-stripping / obfuscation but is a big toggle You can actually decompose it so you get the native shrinking (which is pretty important for mobile apps) but without getting the obfuscation (which is not important at all for us here since all the native code is open source unless you have some mixed native code in there - and even then probably not important)

https://stackoverflow.com/a/55785351/9910298

You might try that - with minify on but obfuscate off. Please note if you play with shrink resources and turn it on you must have an XML file that tells it to keep some resources it can't determine to keep on it's own because react-native is kind of reflective, see problem description / solution I discovered a while back here: https://twitter.com/fastsquatch/status/1196475279688028160

mikehardy avatar Nov 17 '21 12:11 mikehardy

So I've tested with

removeUnusedCode true
obfuscate false
optimizeCode true

and the problem still occurs, which is interesting. The error itself has the given message image But its still grouped under .java :/ image

Im gonna run a few more tests with various combinations to see if i can figure out exactly what options cause the problem

PetterKnudsen98 avatar Nov 17 '21 14:11 PetterKnudsen98

Anything you find will be interesting - it is a known "hard problem" to de-obfuscate the javascript bundle stacks back to source code but at least that is possible normally if you save all the source maps etc (or can regenerate them). This kind of stack is inscrutable!

mikehardy avatar Nov 17 '21 15:11 mikehardy

The result of

removeUnusedCode false
obfuscate false 
optimizeCode false

image The result of

removeUnusedCode false
obfuscate false 
optimizeCode true

and

removeUnusedCode true
obfuscate true 
optimizeCode false

and

removeUnusedCode true
obfuscate false 
optimizeCode false

and

removeUnusedCode false
obfuscate true
optimizeCode false

image

So interestingly it seems that setting any of the values to true will result in the issue being named .java

PetterKnudsen98 avatar Nov 17 '21 18:11 PetterKnudsen98

Well, dang. I was really hoping removeUnusedCode at least would be possible, with a stretch for optimizeCode. Thanks for running the tests!

mikehardy avatar Nov 17 '21 18:11 mikehardy

Hello 👋, to help manage issues we automatically close stale issues. This issue has been automatically marked as stale because it has not had activity for quite some time. Has this issue been fixed, or does it still require the community's attention?

This issue will be closed in 15 days if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Apr 18 '22 18:04 stale[bot]

We are also seeing this issue and keen to help progress it if possible. It does feel though like there may not be any way to achieve a valid name for the associated non-fatal in Crashlytics in this scenario where the JS has been obfuscated/minified - because how would it be possible to decode the method names and call stack at runtime?

One approach to at least provide more useful information for each JavaScriptError / .java <uknown> non-fatal that we are using is to use logEvent and setAttribute calls before the recordError to supply more information and make filtering and searching within the Crashlytics console easier.

It is also obviously possible to search more granularly than the Crashlytics console allows for different kinds of these JavaScriptError non-fatal instances using BigQuery if the Crashlytics data is exported there.

julianD77 avatar Jun 09 '22 10:06 julianD77

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

github-actions[bot] avatar Dec 05 '22 19:12 github-actions[bot]

It still requires attention. We're considering to abandon Crashlytics because of this 😢 We did not find any workaround, unfortunately.

pierpo avatar Dec 05 '22 19:12 pierpo

Open to ideas here - I think the solution will have to involve some experimentation with generating a stack that is in the format crashlytics expects. What is that? Sadly I'm not exactly sure but the code is open for testing + gathering results of native stacks and javascript stacks to see if we can't bend the javascript stacks on non-fatal issues to be more useful

mikehardy avatar Dec 05 '22 21:12 mikehardy

Hey there. Same issue here. We are receiving random network errors from our users and crashlytics don't provide information about the error. We use an ErrorBoundary to catch our exceptions

Non-fatal Exception: io.invertase.firebase.crashlytics.b

Error: Network Error

Non-fatal Exception: io.invertase.firebase.crashlytics.b: Error: Network Error
       at ._callee$(index.android.bundle:145969:115)
       at .call((native):0:0)
       at .tryCatch(index.android.bundle:9909:23)
       at .invoke(index.android.bundle:10079:32)
       at .anonymous(index.android.bundle:9951:30)
       at .call((native):0:0)
       at .tryCatch(index.android.bundle:9909:23)
       at .invoke(index.android.bundle:9981:30)
       at .anonymous(index.android.bundle:10011:19)
       at .tryCallTwo(InternalBytecode.js:61:9)
       at .doResolve(InternalBytecode.js:216:25)
       at .Promise(InternalBytecode.js:82:14)
       at .callInvokeWithMethodAndArg(index.android.bundle:10010:33)
       at .enqueue(index.android.bundle:10015:157)
       at .anonymous(index.android.bundle:9951:30)
       at .anonymous(index.android.bundle:10030:69)
       at ._callee(index.android.bundle:145930:38)
       at .tryCallOne(InternalBytecode.js:53:16)
       at .anonymous(InternalBytecode.js:139:27)
       at .apply((native):0:0)
       at .anonymous(index.android.bundle:10660:26)
       at ._callTimer(index.android.bundle:10570:17)
       at ._callReactNativeMicrotasksPass(index.android.bundle:10599:17)
       at .callReactNativeMicrotasks(index.android.bundle:10805:44)
       at .__callReactNativeMicrotasks(index.android.bundle:2250:46)
       at .anonymous(index.android.bundle:2125:45)
       at .__guard(index.android.bundle:2233:15)
       at .flushedQueue(index.android.bundle:2124:21)
       at .callFunctionReturnFlushedQueue(index.android.bundle:2106:33)

sebasbeleno avatar Dec 12 '22 05:12 sebasbeleno

If there are line numbers into the android bundle, and you have a version control tag for the release code that generated the bundle, you may regenerate the bundle with source maps during all the transpiles and packaging and back track to the source line number I think? Crashlytics doesn't store dynamic language sourcemaps like that so you have to do that locally but there is discussion on stackoverflow and in this issue repo related to it

mikehardy avatar Dec 12 '22 16:12 mikehardy

Hey there. Same issue here. Non-fatal issues in the crashlytics dashboard are simply shown as '.java' for android in production. We use an ErrorBoundary to catch our exceptions

Harsh-oyo avatar Dec 29 '22 12:12 Harsh-oyo

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

github-actions[bot] avatar Jan 26 '23 12:01 github-actions[bot]