import { Button, Card, Center, Code, Group, ScrollArea, Stack, Text, Title } from '@mantine/core'; import { openModal } from '@mantine/modals'; import { IconBrandGithub, IconBug, IconInfoCircle, IconRefresh } from '@tabler/icons-react'; import Consola from 'consola'; import { withTranslation } from 'next-i18next'; import React, { ReactNode } from 'react'; import { WidgetsMenu } from '~/components/Dashboard/Tiles/Widgets/WidgetsMenu'; import { IWidget } from './widgets'; type ErrorBoundaryState = { hasError: boolean; error: Error | undefined; }; type ErrorBoundaryProps = { t: (key: string) => string; children: ReactNode; integration: string; widget: IWidget; }; /** * A custom error boundary, that catches errors within widgets and renders an error component. * The error component can be refreshed and shows a modal with error details */ class ErrorBoundary extends React.Component { constructor(props: any) { super(props); // Define a state variable to track whether is an error or not this.state = { hasError: false, error: undefined }; } static getDerivedStateFromError(error: Error) { // Update state so the next render will show the fallback UI return { hasError: true, error }; } componentDidCatch(error: Error, errorInfo: any) { Consola.error(`Error while rendering widget, ${error}: ${errorInfo}`); } render() { // Check if the error is thrown if (this.state.hasError) { return ( ({ backgroundColor: theme.colors.red[5], })} radius="lg" shadow="sm" withBorder h="calc(100% - 20px)" >
{this.props.t('card.title')} {this.state.error && ( {this.state.error.toString()} )} ), }) } leftIcon={} variant="light" > {this.props.t('card.buttons.details')}
); } // Return children components in case of no error return this.props.children; } } export default withTranslation('widgets/error-boundary')(ErrorBoundary);