import { Component, type ErrorInfo, type ReactNode } from 'react'; interface Props { children: ReactNode; /** Optional fallback rendered in place of `children` when an error is caught. */ fallback?: (error: Error) => ReactNode; } interface State { error: Error | null; } /** * Catches render errors in its subtree and renders a fallback instead of * letting them crash the whole page. Used to isolate failures in part viewers * (e.g. WebGL context loss, texture/trace load errors). */ export default class ErrorBoundary extends Component { override state: State = { error: null }; static getDerivedStateFromError(error: Error): State { return { error }; } override componentDidCatch(error: Error, info: ErrorInfo) { // Surface the error for debugging without breaking the UI. console.error('Part viewer error:', error, info.componentStack); } override render() { if (this.state.error) { return this.props.fallback ? this.props.fallback(this.state.error) : ; } return this.props.children; } } function DefaultFallback({ error }: { error: Error }) { return (

Couldn't render this part

{error.message}

{error.stack && (
          {error.stack}
        
)}
); }