import { Component, FC, ReactNode, ErrorInfo } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faBomb } from "@fortawesome/free-solid-svg-icons/faBomb"; interface InternalErrorProps { message: ReactNode; secondsLeft: number; progressLeft: number; } const InternalError: FC = (props) => (

Internal error

{props.message}

This page will auto refresh in {props.secondsLeft}s

); interface ErrorBoundaryProps { children: React.ReactNode; } interface ErrorBoundaryState { cachedError: Error | null; reloadSeconds: number; } class ErrorBoundary extends Component { timer: ReturnType | null; state: Readonly = { cachedError: null, reloadSeconds: 60, }; constructor(props: ErrorBoundaryProps) { super(props); this.timer = null; } reloadApp = (): void => { if (this.state.reloadSeconds <= 1) { window.location.reload(); } else { this.setState({ reloadSeconds: this.state.reloadSeconds - 1 }); } }; componentDidCatch(error: Error, { componentStack }: ErrorInfo): void { if (this.state.cachedError === null) { this.setState({ cachedError: error }); } // reload after 60s, this is to fix wall monitors automatically // but only if the timer isn't set yet if (this.timer === null) { this.timer = setInterval(this.reloadApp, 1000); } } render(): ReactNode { if (this.state.cachedError !== null) { return ( ); } return this.props.children; } } export { ErrorBoundary, InternalError };