about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/view/com/util/ErrorBoundary.tsx40
-rw-r--r--src/view/shell/mobile/index.tsx23
2 files changed, 55 insertions, 8 deletions
diff --git a/src/view/com/util/ErrorBoundary.tsx b/src/view/com/util/ErrorBoundary.tsx
new file mode 100644
index 000000000..017265f48
--- /dev/null
+++ b/src/view/com/util/ErrorBoundary.tsx
@@ -0,0 +1,40 @@
+import React, {Component, ErrorInfo, ReactNode} from 'react'
+import {ErrorScreen} from './error/ErrorScreen'
+
+interface Props {
+  children?: ReactNode
+}
+
+interface State {
+  hasError: boolean
+  error: any
+}
+
+export class ErrorBoundary extends Component<Props, State> {
+  public state: State = {
+    hasError: false,
+    error: undefined,
+  }
+
+  public static getDerivedStateFromError(error: Error): State {
+    return {hasError: true, error}
+  }
+
+  public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
+    console.error('Uncaught error:', error, errorInfo)
+  }
+
+  public render() {
+    if (this.state.hasError) {
+      return (
+        <ErrorScreen
+          title="Oh no!"
+          message="There was an unexpected issue in the application. Please let us know if this happened to you!"
+          details={this.state.error.toString()}
+        />
+      )
+    }
+
+    return this.props.children
+  }
+}
diff --git a/src/view/shell/mobile/index.tsx b/src/view/shell/mobile/index.tsx
index efa649753..07fdfc843 100644
--- a/src/view/shell/mobile/index.tsx
+++ b/src/view/shell/mobile/index.tsx
@@ -31,6 +31,7 @@ import {HorzSwipe} from '../../com/util/gestures/HorzSwipe'
 import {Modal} from '../../com/modals/Modal'
 import {Lightbox} from '../../com/lightbox/Lightbox'
 import {Text} from '../../com/util/text/Text'
+import {ErrorBoundary} from '../../com/util/ErrorBoundary'
 import {TabsSelector} from './TabsSelector'
 import {Composer} from './Composer'
 import {s, colors} from '../../lib/styles'
@@ -327,7 +328,9 @@ export const MobileShell: React.FC = observer(() => {
         end={{x: 0, y: 1}}
         style={styles.outerContainer}>
         <SafeAreaView style={styles.innerContainer}>
-          <Login />
+          <ErrorBoundary>
+            <Login />
+          </ErrorBoundary>
         </SafeAreaView>
         <Modal />
       </LinearGradient>
@@ -337,7 +340,9 @@ export const MobileShell: React.FC = observer(() => {
     return (
       <View style={styles.outerContainer}>
         <View style={styles.innerContainer}>
-          <Onboard />
+          <ErrorBoundary>
+            <Onboard />
+          </ErrorBoundary>
         </View>
       </View>
     )
@@ -400,12 +405,14 @@ export const MobileShell: React.FC = observer(() => {
                             ]
                           : undefined,
                       ]}>
-                      <Com
-                        params={params}
-                        navIdx={navIdx}
-                        visible={current}
-                        scrollElRef={current ? scrollElRef : undefined}
-                      />
+                      <ErrorBoundary>
+                        <Com
+                          params={params}
+                          navIdx={navIdx}
+                          visible={current}
+                          scrollElRef={current ? scrollElRef : undefined}
+                        />
+                      </ErrorBoundary>
                     </Animated.View>
                   </Screen>
                 )