diff --git a/packages/one/src/router/useScreens.tsx b/packages/one/src/router/useScreens.tsx index 28797712d..5d0a8087d 100644 --- a/packages/one/src/router/useScreens.tsx +++ b/packages/one/src/router/useScreens.tsx @@ -8,7 +8,7 @@ import type { ScreenListeners, } from '@react-navigation/native' import React, { memo, Suspense, useId } from 'react' -import { Text } from 'react-native' +import { SafeAreaView, ScrollView, View, TouchableOpacity, Text } from 'react-native' import { ServerContextScript } from '../server/ServerContextScript' import { getPageExport } from '../utils/getPageExport' import { EmptyRoute } from '../views/EmptyRoute' @@ -374,33 +374,92 @@ function routeToScreen( ) } +type RouteErrorBoundaryState = { hasError: boolean; error: any; errorInfo: any } + +const ROUTE_ERROR_BOUNDARY_INITIAL_STATE = { + hasError: false, + error: null, + errorInfo: null, +} + class RouteErrorBoundary extends React.Component< { children: React.ReactNode; routeName: string }, - { hasError: boolean; error: any } + RouteErrorBoundaryState > { constructor(props) { super(props) - this.state = { hasError: false, error: null } + this.state = ROUTE_ERROR_BOUNDARY_INITIAL_STATE } static getDerivedStateFromError(error) { return { hasError: true, error } } - componentDidCatch(error, info) { + componentDidCatch(error, errorInfo) { console.error( - `Error occurred while running route ${this.props.routeName}: ${ + `Error occurred while running route "${this.props.routeName}": ${ error instanceof Error ? error.message : error - }`, - error, - info.componentStack + }\n\n${error.stack}\n\nComponent Stack:\n${errorInfo.componentStack}` ) + this.setState({ errorInfo }) + } + + clearError() { + this.setState(ROUTE_ERROR_BOUNDARY_INITIAL_STATE) } render() { if (this.state.hasError) { - const error = this.state.error - return Error: {error instanceof Error ? error.message : error} + const { error, errorInfo } = this.state + return ( + + + + Error on route "{this.props.routeName}" + + + {error instanceof Error ? error.message : error} + + + + Retry + + + + {error instanceof Error ? ( + + {error.stack} + + ) : null} + {errorInfo?.componentStack ? ( + + Component Stack: {errorInfo.componentStack} + + ) : null} + + + + ) } return this.props.children