/** * 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 } }