/** * ErrorBoundary — catches render/runtime errors in the calendar tree and shows a * readable fallback instead of a blank white page. * * A white-screen-on-error calendar is unacceptable UX (the non-technical Apple member * would just see nothing). This boundary degrades gracefully and surfaces the error * text + component stack so failures are diagnosable in the field. */ import React from 'react'; interface ErrorBoundaryProps { children: React.ReactNode; } interface ErrorBoundaryState { error: Error | null; info: string | null; } export class ErrorBoundary extends React.Component { state: ErrorBoundaryState = { error: null, info: null }; static getDerivedStateFromError(error: Error): Partial { return { error }; } componentDidCatch(error: Error, info: React.ErrorInfo) { // Log for DevTools / future telemetry; also kept in state for on-screen display. console.error('[CalendarShell crash]', error, info.componentStack); this.setState({ info: info.componentStack ?? null }); } render() { if (this.state.error) { return (

The calendar hit an error

{String(this.state.error?.message ?? this.state.error)}

            {this.state.error?.stack}
            {this.state.info ? '\n\n--- component stack ---' + this.state.info : ''}
          
); } return this.props.children; } }