import Consola from 'consola'; import React, { ReactNode } from 'react'; import { openModal } from '@mantine/modals'; import { withTranslation } from 'next-i18next'; import { Button, Card, Center, Code, Group, Stack, Text, Title } from '@mantine/core'; import { IconBrandGithub, IconBug, IconInfoCircle, IconRefresh } from '@tabler/icons'; type ErrorBoundaryState = { hasError: boolean; error: Error | undefined; }; type ErrorBoundaryProps = { t: (key: string) => string; children: ReactNode; }; /** * 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 >
{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);