import React, { PropsWithChildren } from 'react' import { Log } from '../../utils/native_adapters/configuration' import { ReportErrorScope } from '../../utils/native_adapters/log' import { ResponseError } from '../../utils/response_error' export type ErrorBoundaryFallback = | React.ReactNode | ((error: Error, reset: () => void) => React.ReactNode) export type ErrorBoundaryProps = { scope?: ReportErrorScope screenName?: string fallback?: ErrorBoundaryFallback } type ErrorBoundaryState = { error: Error | null } export class ErrorBoundary extends React.Component< PropsWithChildren, ErrorBoundaryState > { state: ErrorBoundaryState = { error: null } static getDerivedStateFromError(error: Error): ErrorBoundaryState { return { error } } componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { if (error instanceof ResponseError) return Log.reportError(error, { componentStack: errorInfo.componentStack ?? undefined, scope: this.props.scope, screenName: this.props.screenName, tags: { team: 'chat', package: 'chat-react-native' }, }) } handleReset = () => { this.setState({ error: null }) } render() { if (!this.state.error) return this.props.children const { fallback } = this.props if (fallback === undefined) return null return typeof fallback === 'function' ? fallback(this.state.error, this.handleReset) : fallback } }