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 ;
}