added error boundary (#540)

added error boundary
this prevents any faulty components to completely crash the app and instead shows this page with some help about what to do and where to report bugs.
This commit is contained in:
Philip Molares 2020-09-07 20:18:03 +02:00 committed by GitHub
parent aa0589e0b1
commit 2d3d587c78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 44 deletions

View file

@ -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<unknown>) {
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<string, unknown> | ReactNodeArray {
if (this.state.hasError) {
return (
<Container className="text-white d-flex flex-column mvh-100">
<div className='text-white d-flex flex-column align-items-center justify-content-center my-5'>
<h1>An unknown error occurred</h1>
<p>Don't worry, this happens sometimes. If this is the first time you see this page then try reloading the app.</p>
If you can reproduce this error, then we would be glad if you <ExternalLink text={'open an issue on github'} href={frontendVersion.issueTrackerUrl} className={'text-primary'}/> or <ExternalLink text={'contact us on matrix.'} href={'https://riot.im/app/#/room/#hedgedoc:matrix.org'} className={'text-primary'}/>
<Button onClick={() => this.refreshPage()} title={'Reload App'} className={'mt-4'}>
<ForkAwesomeIcon icon={'refresh'}/>&nbsp;Reload App
</Button>
</div>
</Container>
)
}
return this.props.children
}
}

View file

@ -3,23 +3,25 @@ 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(
<Provider store={store}>
<Router>
<ApplicationLoader>
<ErrorBoundary>
<Switch>
<Route path="/history">
<LandingLayout>
@ -59,6 +61,7 @@ ReactDOM.render(
<NotFoundErrorScreen/>
</Route>
</Switch>
</ErrorBoundary>
</ApplicationLoader>
</Router>
</Provider>