Skip to content

Commit

Permalink
Merge pull request #1061 from bugsnag/integration/rn-native-stack
Browse files Browse the repository at this point in the history
[PLAT-5002] Include native stacktraces JS errors caused by native promise rejections
  • Loading branch information
bengourley authored Oct 1, 2020
2 parents 2e05394 + fc53d42 commit f4e6876
Show file tree
Hide file tree
Showing 240 changed files with 31,236 additions and 584 deletions.
6 changes: 6 additions & 0 deletions examples/reactnative/rn060example/.buckconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

[android]
target = Google Inc.:Google APIs:23

[maven_repositories]
central = https://repo1.maven.org/maven2
4 changes: 4 additions & 0 deletions examples/reactnative/rn060example/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: '@react-native-community',
};
99 changes: 99 additions & 0 deletions examples/reactnative/rn060example/.flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
[ignore]
; We fork some components by platform
.*/*[.]android.js

; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/

; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*

; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
node_modules/react-native/Libraries/react-native/React.js

; Ignore polyfills
node_modules/react-native/Libraries/polyfills/.*

; These should not be required directly
; require from fbjs/lib instead: require('fbjs/lib/warning')
node_modules/warning/.*

; Flow doesn't support platforms
.*/Libraries/Utilities/HMRLoadingView.js

[untyped]
.*/node_modules/@react-native-community/cli/.*/.*

[include]

[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow/

[options]
emoji=true

esproposal.optional_chaining=enable
esproposal.nullish_coalescing=enable

module.file_ext=.js
module.file_ext=.json
module.file_ext=.ios.js

module.system=haste
module.system.haste.use_name_reducers=true
# get basename
module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1'
# strip .js or .js.flow suffix
module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1'
# strip .ios suffix
module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1'
module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
module.system.haste.paths.blacklist=.*/__tests__/.*
module.system.haste.paths.blacklist=.*/__mocks__/.*
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/RNTester/.*
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/IntegrationTests/.*
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation.js
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/Animated/src/polyfills/.*

munge_underscores=true

module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'

suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState

suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError

[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
sketchy-number=warn
untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
inexact-spread=warn
unnecessary-invariant=warn
signature-verification-failure=warn
deprecated-utility=error

[strict]
deprecated-type
nonstrict-import
sketchy-null
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import

[version]
^0.98.0
1 change: 1 addition & 0 deletions examples/reactnative/rn060example/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pbxproj -text
59 changes: 59 additions & 0 deletions examples/reactnative/rn060example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# OSX
#
.DS_Store

# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace

# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml

# node.js
#
node_modules/
npm-debug.log
yarn-error.log

# BUCK
buck-out/
\.buckd/
*.keystore

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/

*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots

# Bundle artifact
*.jsbundle

# CocoaPods
/ios/Pods/
1 change: 1 addition & 0 deletions examples/reactnative/rn060example/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
177 changes: 177 additions & 0 deletions examples/reactnative/rn060example/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/

import React from 'react';
import {
Button,
SafeAreaView,
StyleSheet,
ScrollView,
View,
Text,
StatusBar,
} from 'react-native';

import { NativeModules } from 'react-native';

// Setup Bugsnag client to capture errors automatically
import Bugsnag from '@bugsnag/react-native'
Bugsnag.start();

function triggerException() {
bogusFunction(); // eslint-disable-line no-undef
}

function triggerHandledException() {
bogusHandledFunction(); // eslint-disable-line no-undef
}

function triggerPromiseRejection() {
NativeModules.CrashyCrashy.generatePromiseRejection();
}

function triggerNativeException() {
NativeModules.CrashyCrashy.generateCrash()
}

function triggerNativeHandledError() {
NativeModules.CrashyCrashy.handledError()
}

const App: () => React$Node = () => {
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
{global.HermesInternal == null ? null : (
<View style={styles.engine}>
<Text style={styles.footer}>Engine: Hermes</Text>
</View>
)}
<View style={styles.container}>
<Text style= {{
paddingTop: 40,
margin: 20,
}}>Press the buttons below to test examples of Bugsnag functionality. Make sure you have changed the API key in Info.plist or AndroidManifest.xml.</Text>
<ScrollView>
<View style={styles.buttonContainer}>

<Button
title="Trigger JS Exception"
onPress={triggerException} />
<Text style={styles.info}>
Tap this button to send a JS crash to Bugsnag
</Text>

<Button
title="Trigger Native Exception"
onPress={triggerNativeException} />
<Text style={styles.info}>
Tap this button to send a native {Platform.OS} crash to Bugsnag
</Text>

<Button
title="Send Handled JS Exception"
onPress={() => {
try { // execute crashy code
triggerHandledException();
} catch (error) {
Bugsnag.notify(error);
}
}} />
<Text style={styles.info}>
Tap this button to send a handled error to Bugsnag
</Text>

<Button
title="Trigger Promise Rejection"
onPress={() => {
try { // execute crashy code
triggerPromiseRejection();
} catch (error) {
Bugsnag.notify(error);
}
}} />
<Text style={styles.info}>
Tap this button to send a promise rejection to Bugsnag
</Text>

<Button
title="Send Handled Native Exception"
onPress={() => {
triggerNativeHandledError()
}} />
<Text style={styles.info}>
Tap this button to send a native handled error to Bugsnag
</Text>

<Button
title="Set user"
onPress={() => {
try { // execute crashy code
throw new Error("Error with user");
} catch (error) {
Bugsnag.setUser("user-5fab67", "[email protected]", "John Smith");
Bugsnag.notify(error);
}
}} />
<Text style={styles.info}>
Tap this button to send a handled error with user information to Bugsnag
</Text>

<Button
title="Leave breadcrumbs"
onPress={() => {
// log a breadcrumb, which will be attached to the error report
Bugsnag.leaveBreadcrumb('About to execute crashy code', {
type: 'user'
});

try { // execute crashy code
throw new Error("Error with breadcrumbs");
} catch (error) {
Bugsnag.notify(error);
}
}} />
<Text style={styles.info}>
Tap this button to send a handled error with manual breadcrumbs
</Text>

</View>
</ScrollView>
</View>
</ScrollView>
</SafeAreaView>
</>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#eeeeee',
},
buttonContainer: {
margin: 20
},
info: {
textAlign: 'center',
color: '#666',
fontSize: 11,
marginBottom: 20
}
})


export default App;
14 changes: 14 additions & 0 deletions examples/reactnative/rn060example/__tests__/App-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @format
*/

import 'react-native';
import React from 'react';
import App from '../App';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
renderer.create(<App />);
});
Loading

0 comments on commit f4e6876

Please sign in to comment.