import React from 'react'; import {DefinitionList, Flex, Text} from '@gravity-ui/uikit'; import QRCode from 'qrcode'; import {ErrorBoundary as ErrorBoundaryBase} from 'react-error-boundary'; import {cn} from '../../utils/cn'; import {getIllustration} from '../../utils/illustrations'; import {registerError} from '../../utils/registerError'; import {useComponent} from '../ComponentsProvider/ComponentsProvider'; import i18n from './i18n'; import type {DiagnosticsData} from './utils'; import {collectDiagnosticsData, prepareErrorStack} from './utils'; import './ErrorBoundary.scss'; const b = cn('ydb-error-boundary'); export function ErrorBoundary({children}: {children?: React.ReactNode}) { const ErrorBoundaryComponent = useComponent('ErrorBoundary'); return {children}; } interface ErrorBoundaryProps { children?: React.ReactNode; } export function ErrorBoundaryInner({children}: ErrorBoundaryProps) { return ( { registerError(error, info.componentStack ?? undefined, 'error-boundary'); }} fallbackRender={({error}) => { return ; }} > {children} ); } interface ErrorBoundaryFallbackProps { error: Error; } export function ErrorBoundaryFallback({error}: ErrorBoundaryFallbackProps) { const [diagnosticsData, setDiagnosticsData] = React.useState(); React.useEffect(() => { const database = new URLSearchParams(window.location.search).get('database') ?? undefined; collectDiagnosticsData(error, database).then((data) => { setDiagnosticsData(data); }); }, [error]); const InternalErrorImage = getIllustration('InternalError'); return ( {i18n('error-title')} {i18n('error-description')} {i18n('send-qr-message')} ); } function DiagnosticsDataList({data}: {data?: DiagnosticsData}) { return ( {data?.uiVersion && typeof data.uiVersion === 'string' && ( {data.uiVersion} )} {data?.backendVersion && typeof data.backendVersion === 'string' && ( {data.backendVersion} )} {data?.error.message} ); } function ErrorStack({stack}: {stack?: string}) { if (!stack) { return null; } const stackToDisplay = prepareErrorStack(stack, { trim: false, maxLines: undefined, }); return ( {i18n('stack-title')} {stackToDisplay} ); } function DiagnosticsDataQR({data}: {data?: DiagnosticsData}) { const canvasRef = React.useRef(null); React.useEffect(() => { if (data) { QRCode.toCanvas(canvasRef.current, JSON.stringify(data), { errorCorrectionLevel: 'L', width: 400, }); } }, [data]); if (!data) { return null; } return ; }