Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PLAT-5002] Include native stacktraces JS errors caused by native promise rejections #1061

Merged
merged 26 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9c18735
feat(react-native): Pass nativeStack to native layer if it exists
bengourley Sep 14, 2020
bc3200d
test(react-native): Create placeholder assertions JS errors with nati…
bengourley Sep 15, 2020
7ed53b3
feat: record "nativeStack" in an error
nickdowell Sep 18, 2020
5d8de04
Update bugsnag-cocoa
nickdowell Sep 21, 2020
b8e562b
test(react-native): Spike out tests for native stack
bengourley Sep 15, 2020
0cfd3af
dep: update RN Android AAR to support nativeStack error parsing
fractalwrench Sep 18, 2020
847b0c6
Merge pull request #1063 from bugsnag/PLAT-5001/native-stack
fractalwrench Sep 22, 2020
37e73f5
fix(react-native): Specify Cocoa error type for native promise reject…
nickdowell Sep 22, 2020
ba8a701
Merge pull request #1062 from bugsnag/rn-native-stack-ios
fractalwrench Sep 22, 2020
7d4f3d4
chore: add example app for React Native 0.60.0
fractalwrench Sep 24, 2020
52705a8
dep: update RN android dependency
fractalwrench Sep 24, 2020
65e3d02
Merge pull request #1069 from bugsnag/rn-native-stack/update-android
fractalwrench Sep 24, 2020
d816984
dep: bump RN bugsnag-cocoa version to next
fractalwrench Sep 25, 2020
b930904
test: verify native stacktrace parising of RN promise rejection
fractalwrench Sep 24, 2020
8fa0ea3
Merge pull request #1068 from bugsnag/rn-native-stack/example-app
fractalwrench Sep 25, 2020
bbdf5bf
Merge pull request #1070 from bugsnag/rn-native-stack/update-ios
fractalwrench Sep 25, 2020
6325c90
Merge pull request #1066 from bugsnag/rn-native-stack/mazerunner-tests
bengourley Sep 28, 2020
c6f82f6
dep(react-native): update cocoa notifier to v6.1.6
bengourley Sep 28, 2020
db828ee
Merge branch 'next' into integration/rn-native-stack
bengourley Sep 28, 2020
1d146c1
chore: Update changelog
bengourley Sep 28, 2020
5f345ca
dep(react-native): Bump cocoa to latest next
bengourley Sep 28, 2020
d76429d
refactor(examples): Handle native promise rejection so that it works …
bengourley Sep 28, 2020
390379a
refactor(react-native): Hold nativeStack feature until pipeline suppo…
bengourley Sep 29, 2020
97ffaa3
Merge branch 'next' into integration/rn-native-stack
bengourley Sep 29, 2020
1ccead2
test(delivery-react-native): Skip tests for commented out feature
bengourley Sep 29, 2020
fc53d42
test(react-native): @skip annotation doesn't work
bengourley Sep 30, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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", "john@example.com", "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