diff --git a/shared/common-adapters/error-boundary.tsx b/shared/common-adapters/error-boundary.tsx index 29339ac1ccab..4e283d323012 100644 --- a/shared/common-adapters/error-boundary.tsx +++ b/shared/common-adapters/error-boundary.tsx @@ -6,6 +6,52 @@ import Icon from './icon' import logger from '@/logger' import * as Styles from '@/styles' +type BareFallbackRenderProps = { + error: Error + resetErrorBoundary: () => void +} + +type BareProps = { + children: React.ReactNode + fallback?: React.ReactNode + fallbackRender?: (props: BareFallbackRenderProps) => React.ReactNode + onError?: (error: Error, info: React.ErrorInfo) => void +} + +type BareState = { + error?: Error +} + +export class BareErrorBoundary extends React.Component { + state: BareState = {} + + static getDerivedStateFromError(error: Error): BareState { + return {error} + } + + componentDidCatch(error: Error, info: React.ErrorInfo) { + this.props.onError?.(error, info) + } + + resetErrorBoundary = () => { + this.setState({error: undefined}) + } + + render(): React.ReactNode { + const {children, fallback, fallbackRender} = this.props + const {error} = this.state + + if (error) { + if (fallbackRender) { + return fallbackRender({error, resetErrorBoundary: this.resetErrorBoundary}) + } + return fallback ?? null + } + + return children + } +} + type AllErrorInfo = { name: string message: string @@ -86,8 +132,6 @@ type Props = { fallbackStyle?: Styles.StylesCrossPlatform } -import {ErrorBoundary} from 'react-error-boundary' - const EB = (p: Props) => { const {children, fallbackStyle, closeOnClick} = p const [componentStack, setComponentStack] = React.useState('') @@ -108,9 +152,9 @@ const EB = (p: Props) => { } return ( - + {children} - + ) } diff --git a/shared/common-adapters/markdown/index.tsx b/shared/common-adapters/markdown/index.tsx index 2abedf713832..e107f6ad70ac 100644 --- a/shared/common-adapters/markdown/index.tsx +++ b/shared/common-adapters/markdown/index.tsx @@ -1,6 +1,7 @@ import * as Styles from '@/styles' import type * as React from 'react' import * as SM from '@khanacademy/simple-markdown' +import {BareErrorBoundary} from '@/common-adapters/error-boundary' import Text from '@/common-adapters/text' import logger from '@/logger' import {emojiIndexByChar, emojiRegex, commonTlds} from './emoji-gen' @@ -14,7 +15,6 @@ import { } from './react' import type * as T from '@/constants/types' import type {StylesTextCrossPlatform, LineClampType} from '@/common-adapters/text.shared' -import {ErrorBoundary} from 'react-error-boundary' const SimpleMarkdown = SM.default @@ -541,7 +541,7 @@ function SimpleMarkdownComponent(p: Props) { // Mobile doesn't use a wrapper return ( - {children}}> + {children}}> {Styles.isMobile ? ( inner ) : ( @@ -555,7 +555,7 @@ function SimpleMarkdownComponent(p: Props) { {inner} )} - + ) } diff --git a/shared/package.json b/shared/package.json index bf449aae3777..32e48cba3040 100644 --- a/shared/package.json +++ b/shared/package.json @@ -120,7 +120,6 @@ "menubar": "9.5.2", "react": "19.2.0", "react-dom": "19.2.0", - "react-error-boundary": "5.0.0", "react-native": "0.83.4", "react-native-gesture-handler": "3.0.0-beta.2", "react-native-kb": "file:../rnmodules/react-native-kb",