diff --git a/src/App.tsx b/src/App.tsx
index c00c435..e3d08ad 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -21,28 +21,24 @@ import ProductDetailScreen from './screens/ProductDetailScreen';
import ReduxScreen from './screens/ReduxScreen';
import CartScreen from './screens/CartScreen';
import CheckoutScreen from './screens/CheckoutScreen';
-import Toast from 'react-native-toast-message';
-import {RootState, store, showFeedbackActionButton} from './reduxApp';
-import {DSN} from './config';
+import {RootState, store} from './reduxApp';
import {SE} from '@env'; // SE is undefined if no .env file is set
import {RootStackParamList} from './navigation';
import {GestureHandlerRootView} from 'react-native-gesture-handler';
-import {LogBox, Platform, StyleSheet} from 'react-native';
+import {LogBox, Platform, Pressable, StyleSheet, Text, View} from 'react-native';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {SentryUserFeedbackActionButton} from './components/UserFeedbackModal';
+import {DSN} from './config';
console.log('> SE', SE);
LogBox.ignoreAllLogs();
-const reactNavigationIntegration =
- Sentry.reactNavigationIntegration({
- // How long it will wait for the route change to complete. Default is 1000ms
- routeChangeTimeoutMs: 500,
- enableTimeToInitialDisplay: true,
- });
+const reactNavigationIntegration = Sentry.reactNavigationIntegration({
+ routeChangeTimeoutMs: 500,
+ enableTimeToInitialDisplay: true,
+});
-// Get app version from package.json, for fingerprinting
const packageJson = require('../package.json');
Sentry.init({
@@ -50,25 +46,17 @@ Sentry.init({
debug: true,
environment: 'dev',
enableLogs: true,
- beforeSend: (event) => {
+ beforeSend: event => {
if (SE === 'tda') {
- // Make issues unique to the release (app version) for Release Health
event.fingerprint = ['{{ default }}', SE, packageJson.version];
} else if (SE) {
- // Make issue for the SE
event.fingerprint = ['{{ default }}', SE];
}
-
- if (!event.type) {
- // Only show the feedback button for errors
- store.dispatch(showFeedbackActionButton());
- }
-
return event;
},
integrations: [
Sentry.reactNativeTracingIntegration({
- traceFetch: false, // RN uses XHR to implement fetch, this prevents duplicates
+ traceFetch: false,
}),
Sentry.mobileReplayIntegration({
maskAllImages: true,
@@ -83,8 +71,8 @@ Sentry.init({
replaysSessionSampleRate: 1.0,
enableUserInteractionTracing: true,
enableAutoSessionTracking: true,
- sessionTrackingIntervalMillis: 5000, // For testing, session close when 5 seconds (instead of the default 30) in the background.
- maxBreadcrumbs: 150, // Extend from the default 100 breadcrumbs.
+ sessionTrackingIntervalMillis: 5000,
+ maxBreadcrumbs: 150,
attachStacktrace: true,
attachScreenshot: true,
attachViewHierarchy: true,
@@ -93,6 +81,15 @@ Sentry.init({
Sentry.setTag('se', SE);
+const FallbackComponent = ({resetError}: {resetError: () => void}) => (
+
+ Something went wrong.
+
+ Refresh
+
+
+);
+
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
@@ -116,10 +113,10 @@ const App = () => {
customerType,
email,
se: SE,
- version: packageJson.version,
});
return (
+
@@ -138,6 +135,7 @@ const App = () => {
+
);
};
@@ -242,11 +240,27 @@ const styles = StyleSheet.create({
gestureHandlerRootView: {
flex: 1,
},
-});
-
-export default Sentry.wrap(App, {
- touchEventBoundaryProps: {
- ignoreNames: ['Provider', 'UselessName', /^SomeRegex/],
- labelName: 'id',
+ fallback: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: '#fff',
+ },
+ fallbackText: {
+ fontSize: 18,
+ marginBottom: 20,
+ color: '#000',
+ },
+ fallbackButton: {
+ paddingHorizontal: 24,
+ paddingVertical: 12,
+ backgroundColor: '#002626',
+ borderRadius: 8,
+ },
+ fallbackButtonText: {
+ color: '#fff',
+ fontWeight: 'bold',
},
});
+
+export default Sentry.wrap(App);
diff --git a/src/components/ErrorBoundaryProduct.tsx b/src/components/ErrorBoundaryProduct.tsx
new file mode 100644
index 0000000..fc20ada
--- /dev/null
+++ b/src/components/ErrorBoundaryProduct.tsx
@@ -0,0 +1,90 @@
+import React from 'react';
+import {View, Text, StyleSheet} from 'react-native';
+import Icon from 'react-native-vector-icons/FontAwesome6';
+import {StyledButton} from './StyledButton';
+
+const BuggyCart = (): React.ReactElement => {
+ return (
+ {
+ throw new Error('Error boundary triggered from error product card');
+ }}
+ style={{
+ default: styles.addToCartButton,
+ pressed: styles.addToCartButton,
+ }}
+ />
+ );
+};
+
+export const ErrorBoundaryProduct = (): React.ReactElement => {
+ return (
+
+
+
+
+
+
+ Error Product
+ Boundary error testing
+
+
+
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ cardContainer: {
+ width: '100%',
+ height: 200,
+ borderWidth: 1,
+ borderColor: '#e74c3c',
+ borderRadius: 6,
+ backgroundColor: '#ffffff',
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ marginVertical: 5,
+ },
+ cardHero: {
+ width: '40%',
+ height: '100%',
+ backgroundColor: '#fdf0f0',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ cardDetail: {
+ flex: 1,
+ height: '100%',
+ flexDirection: 'column',
+ },
+ cardDetailContent: {
+ padding: 10,
+ flex: 1,
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ paddingBottom: 10,
+ },
+ cardDetailAction: {
+ flex: 0,
+ },
+ cardTitle: {
+ marginBottom: 5,
+ fontSize: 24,
+ fontWeight: '500',
+ color: '#c0392b',
+ },
+ cardDescription: {
+ fontSize: 14,
+ color: '#555',
+ },
+ addToCartButton: {
+ margin: 10,
+ },
+});
diff --git a/src/config.ts b/src/config.ts
index 5fc10ea..765c48b 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,5 +1,5 @@
export const DSN =
- 'https://b87682e62e4cc633d4c35c7154256c66@sandbox-mirror.sentry.gg/1';
+ 'https://6d107379901d7674dce67c2cf3a735fe@o88872.ingest.us.sentry.io/4511095053615104';
// SENTRY_INTERNAL_DSN for testing
// export const DSN =
diff --git a/src/screens/HomeScreen.tsx b/src/screens/HomeScreen.tsx
index 01cfc06..8dbef45 100644
--- a/src/screens/HomeScreen.tsx
+++ b/src/screens/HomeScreen.tsx
@@ -6,6 +6,7 @@ import {BACKEND_URL} from '../config';
import {StackScreenProps} from '@react-navigation/stack';
import {RootStackParamList} from '../navigation';
import {ProfiledStyledProductCard} from '../components/StyledProductCard';
+import {ErrorBoundaryProduct} from '../components/ErrorBoundaryProduct';
import {Product} from '../types/Product';
type ExtendedSentryScope = Sentry.Scope & {
@@ -108,6 +109,7 @@ const EmpowerPlant = ({navigation}: StackScreenProps) => {
refreshing={toolData === null}
data={toolData}
contentContainerStyle={styles.productListContainer}
+ ListHeaderComponent={toolData ? : null}
renderItem={({item}) => {
return (