react native convert meaningless stack trace to original source code
When the following code executed, it will crash because it’s trying to access a property a from a null object.
let obj = null; console.log(obj.a);
If the app has Firebase Crashlytics installed, the crash report in Firebase Crashlytics will look like this. It tells us on line 512 and column 973, something is trying to access a property ‘a’ on a ‘null’ object. But this is not very helpful as it doesn’t tell us which file this crash was coming from. In order to figured out which file it is coming from, a source map of the codebase is needed, and then using the source map to trace back the file this is coming from.
Fatal Exception: com.facebook.react.common.JavascriptException TypeError: null is not an object (evaluating 'null.a'), stack: value@512:973 value@-1 touchableHandlePress@217:2269 touchableHandlePress@-1 _performSideEffectsForTransition@208:9693 _performSideEffectsForTransition@-1 _receiveSignal@208:8375 _receiveSignal@-1 touchableHandleResponderRelease@208:5663 touchableHandleResponderRelease@-1 b@91:1197 k@91:1340 C@91:1394 N@91:1692 A@91:2482 forEach@-1 z@91:2282@91:13914 _e@91:88659 Ne@91:13582 Ue@91:13755 receiveTouches@91:14547 value@27:3685 @27:841 value@27:2939 value@27:813 value@-1 com.facebook.react.modules.core.ExceptionsManagerModule.reportException
To generate a source map in react native for Android, add this line in app/build.gradle, then do a release build, and the source map will be generated at the root direction of the react native project.
project.ext.react = [ entryFile: "index.js", enableHermes: false, //add this for generating source map in react native for android extraPackagerArgs: ["--sourcemap-output", file("$buildDir/../../../sourcemap.android.js")] //add this for generating source map in react native for android ]
To generate a source map in react native for IOS, run this command, and the source map will be generated at the root directory of the react native project.
react-native bundle --platform ios --entry-file index.js --dev false --bundle-output ./ios/main.jsbundle --assets-dest ./ios --sourcemap-output ./sourcemap.ios.js
The next step is to map the line number and column number from the above Firebase Crashlytics crash report, to the line number and column number of the original source code where the crash happened. There is a node library called source-map which can be used to do just this. Run this command to install it.
npm install source-map --save
The create a javascript file(sourcemap.js) at the react native root directory with the following code, the line number and the column number from the Firebase Crashlytics crash report is passed into the method originalPositionFor to get the original position of the crash.
const sourceMap = require('source-map'); const fs = require('fs'); fs.readFile('./sourcemap.android.js', 'utf8', async function (err, data) { const whatever = await sourceMap.SourceMapConsumer.with(data, null, consumer => { console.log(consumer.sources); console.log( consumer.originalPositionFor({ line: 512, column: 973 }) ); consumer.eachMapping(function(m) { // ... }); return computeWhatever(); }); });
Then run the above script to find out where exactly the crash was happening in the original source code.
node sourcemap.js
The result will look like this, it reveals which file, which line, and which column the crash was happening in the original source code.
{ source: '/path/to/the/file/where/the/crash/has/happened/MyExampleProject/app/ui/view/LoginScreen.js', line: 20, column: 20, name: 'a' }
Search within Codexpedia
Search the entire web