/** * Error boundary component that catches React errors and tracks them via telemetry. */ import type { ReactNode, ErrorInfo } from "react"; import { Component } from "react"; import { Box, Flex, Heading, Text, Button } from "@radix-ui/themes"; import { telemetry } from "@/telemetry/client"; interface ErrorBoundaryProps { children: ReactNode; fallback?: (error: Error) => ReactNode; } interface ErrorBoundaryState { hasError: boolean; error: Error | null; } class ErrorBoundary extends Component { constructor(props: ErrorBoundaryProps) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error: Error): ErrorBoundaryState { return { hasError: true, error }; } componentDidCatch(error: Error, errorInfo: ErrorInfo): void { // Track the error via telemetry telemetry.track({ name: "error", properties: { errorType: "runtime_error", message: error.message, stack: error.stack, context: { componentStack: errorInfo.componentStack, route: typeof window !== "undefined" ? window.location.pathname : "unknown", }, }, }); // Log to console for debugging console.error("ErrorBoundary caught an error:", error, errorInfo); } render() { if (this.state.hasError && this.state.error) { // If custom fallback is provided, use it if (this.props.fallback) { return this.props.fallback(this.state.error); } // Default fallback UI using Radix components return ( Something went wrong {this.state.error.message} ); } return this.props.children; } } export default ErrorBoundary;