diff --git a/src/components/error-boundary/error-boundary.tsx b/src/components/error-boundary/error-boundary.tsx new file mode 100644 index 000000000..25549729d --- /dev/null +++ b/src/components/error-boundary/error-boundary.tsx @@ -0,0 +1,48 @@ +import React, { Component, ErrorInfo, ReactElement, ReactNodeArray } from 'react' +import { Button, Container } from 'react-bootstrap' +import frontendVersion from '../../version.json' +import { ForkAwesomeIcon } from '../common/fork-awesome/fork-awesome-icon' +import { ExternalLink } from '../common/links/external-link' + +export class ErrorBoundary extends Component { + state: { + hasError: boolean + } + + constructor (props: Readonly) { + super(props) + this.state = { hasError: false } + } + + static getDerivedStateFromError (_error: Error): { hasError: boolean } { + // Update state so the next render will show the fallback UI. + return { hasError: true } + } + + componentDidCatch (error: Error, errorInfo: ErrorInfo): void { + console.error('error caught', error) + console.error('additional information', errorInfo) + } + + refreshPage (): void { + window.location.reload() + } + + render (): ReactElement | undefined | null | string | number | boolean | Record | ReactNodeArray { + if (this.state.hasError) { + return ( + +
+

An unknown error occurred

+

Don't worry, this happens sometimes. If this is the first time you see this page then try reloading the app.

+ If you can reproduce this error, then we would be glad if you or + +
+
+ ) + } + return this.props.children + } +} diff --git a/src/index.tsx b/src/index.tsx index 2ddca1ea9..67cb5478c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -3,62 +3,65 @@ import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom' import { ApplicationLoader } from './components/application-loader/application-loader' -import { Editor } from './components/editor/editor' import { NotFoundErrorScreen } from './components/common/routing/not-found-error-screen' -import { LandingLayout } from './components/landing-layout/landing-layout' +import { Redirector } from './components/common/routing/redirector' +import { Editor } from './components/editor/editor' +import { ErrorBoundary } from './components/error-boundary/error-boundary' import { HistoryPage } from './components/history-page/history-page' import { IntroPage } from './components/intro-page/intro-page' +import { LandingLayout } from './components/landing-layout/landing-layout' import { LoginPage } from './components/login-page/login-page' import { ProfilePage } from './components/profile-page/profile-page' import { RegisterPage } from './components/register-page/register-page' -import { Redirector } from './components/common/routing/redirector' -import './style/index.scss' -import * as serviceWorker from './service-worker' import { store } from './redux' +import * as serviceWorker from './service-worker' +import './style/index.scss' ReactDOM.render( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +