If you enable ProGuard or use the Jack toolchain for your Android builds you can upload the generated mapping file using the Android Mapping Upload API to de-obfuscate the native Android stack traces.
You can upload dSYM files using the dSYM Upload API to symbolicate native iOS stack traces.
Source maps are automatically created when using the React Native Packager on a simulator or can be generated using the
react-native bundle cli.
Once generated the Source Map Upload API can be used to upload the source map and bundle file. The use of this varies depending on the build variant and platform.
The upload API should be used as follows for React Native source maps:
apiKey- the Bugsnag API key that is used in your app.
appVersion- the version of the Android or iOS app that the source map applies to. This can either be the app version or versionCode. See here for more details.
appVersion. See here for details.
minifiedUrl- the location of the bundle file as reported in the stacktrace. For debug builds this is usually the locally hosted packager location (e.g. http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false). For release builds this is usually just the name of the bundle file (e.g. main.jsbundle). Asterisks can be used as a wildcard.
sourceMap- the source map file.
minifiedFile- the bundle file.
overwrite(optional) - specifies whether to overwrite any existing version of the files for this minified url and app version. Defaults to false.
<sources>(optional) - each source file referenced by the source map (if the source hasn’t been included in the
sourcesContentfield of the source map). Each field name should be the full path of the source file as referenced in the
sourcessection of the source map. Asterisks in the field name can be used as a wildcard.
$ curl https://upload.bugsnag.com/ \ -F apiKey=YOUR_API_KEY_HERE \ -F appVersion=1.0 \ -F minifiedUrl="http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false" \ -F sourceMap=@path/to/index.ios.bundle.map \ -F minifiedFile=@path/to/index.ios.bundle \ -F overwrite=true
$ curl https://upload.bugsnag.com/ \ -F apiKey=YOUR_API_KEY_HERE \ -F appVersion=1.0 \ -F minifiedUrl="main.jsbundle" \ -F sourceMap=@path/to/main.jsbundle.map \ -F minifiedFile=@path/to/main.jsbundle \ -F overwrite=true -F /workspace/app/index.ios.js=@/workspace/app/index.ios.js
Source maps get applied to an error based on the url/file in the stacktrace and the version of the app. The bundle file also needs to be uploaded to ensure that mapping and grouping work correctly.
If the uploaded source map isn’t getting applied correctly you should check the following:
minifiedUrlfield specified during upload matches the url/file in the stacktrace. It must exactly match if wildcards haven’t been used or match according to the wildcard logic if they have been used.
appVersionfield either matches the app version or the app versionCode (as seen in the app tab on the error)
Bugsnag needs visibility of the source code in order to display the code context against the lines in the stacktrace.
This can either be achieved by ensuring that the
sourcesContent field is populated correctly in the source map or by uploading
the required source files during source map upload.
When using the debug variant of the
react-native bundle cli it applies the
sourceContent to the source map.
However it doesn’t populate the field with the full source content for the release variant.
The source files can be uploaded to Bugsnag if the
sourcesContent is not populated properly in the source map.
This can be done for each source file during source map upload by specifiying the full path to the source file (as it appears in the mapped stacktrace) as the field name and the file as the value (as shown in the release variant example).
A 422 (Unprocessable Entity) status code is returned with a message of “Nothing to upload” if the files haven’t been uploaded correctly.
This is often due to missing the @ symbol before the file path for the source map file when using cURL. If the @ symbol is omitted the path to the file is sent rather than the file itself.
appVersion field should be the version of the app that the source map applies to.
This should match either the
version or the
versionCode field as it appears in the error report (as seen in the app tab of the error).
The app version and versionCode that appear for the error reports vary depending on the platform:
versionNamesetting and the versionCode is taken from the
versionCodesetting. See here for details of the different Android version settings.
codeBundleId instead of the
You can see details of the source maps that you’ve uploaded by going to Project Settings -> Uploaded source maps.
Once a source map is uploaded it will only get applied to new error events. It does not get applied retrospectively to existing errors events.
The asterisk character can be used as a wildcard for the
minifiedUrl field and source file field names. This adds flexibility when matching a source map against an error report and allows source files to be referenced without the full path to the file.
Multiple wildcards can be used in the same field. Each asterisk matches zero or more characters.
e.g. To allow the path to the source file index.ios.js to be matched without the file path (making it more flexible matching against bundles generated on different machines) the following curl command could be used:
$ curl https://upload.bugsnag.com/ \ -F apiKey=YOUR_API_KEY_HERE \ -F appVersion=1.0 \ -F minifiedUrl="main.jsbundle" \ -F sourceMap=@path/to/main.jsbundle.map \ -F minifiedFile=@path/to/main.jsbundle \ -F overwrite=true -F */index.ios.js=@/workspace/app/index.ios.js
If multiple minified urls in source map uploads match the same minified url/file and app version in an error report (due to the use of wildcards) the most recently uploaded source map matching the url/file and app version will be used on the error.
If multiple source files in an upload match against a source file path (due to the use of wildcards) the selection of source file will be arbitrary.
Define and set a code bundle identifier before your deploy in your Bugsnag configuration. This identifier can be any string as long as it matches what is sent to the source map upload API in step 3.
const config = new Configuration('YOUR_API_KEY_HERE'); config.codeBundleId = '1.0-123' const bugsnag = new Client(config);
Release your app using CodePush, specifying the
--outputDir in order to capture the source map and asset bundle files for upload in step 3.
code-push release-react <appName> <platform> --outputDir <outputDir> <other options>
codeBundleId in the source map upload instead of the
$ curl https://upload.bugsnag.com/ \ -F apiKey=YOUR_API_KEY_HERE \ -F codeBundleId=1.0-123 \ -F minifiedUrl="main.jsbundle" \ -F sourceMap=@path/to/main.jsbundle.map \ -F minifiedFile=@path/to/main.jsbundle \ -F overwrite=true -F */index.ios.js=@/workspace/app/index.ios.js
When a React Native error event is received with a
codeBundleId in the app data we will attempt to find an uploaded source map for the url/file in the stacktrace and a matching codeBundleId. This overrides the normal behaviour that looks up uploaded source maps based on url/file and app version.