forked from Shiloh/remnantchat
feat: add error boundary
This commit is contained in:
parent
69a15443ce
commit
44c328fd1f
74
src/components/ErrorBoundary/ErrorBoundary.tsx
Normal file
74
src/components/ErrorBoundary/ErrorBoundary.tsx
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { Component, ErrorInfo, ReactNode } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import Alert from '@mui/material/Alert'
|
||||||
|
import Box from '@mui/material/Box'
|
||||||
|
import IconButton from '@mui/material/IconButton'
|
||||||
|
import Typography from '@mui/material/Typography'
|
||||||
|
import CloseIcon from '@mui/icons-material/Close'
|
||||||
|
|
||||||
|
import { routes } from 'config/routes'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children?: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
error: Error | null
|
||||||
|
showError: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapted from https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/error_boundaries/
|
||||||
|
export class ErrorBoundary extends Component<Props, State> {
|
||||||
|
public state: State = {
|
||||||
|
error: null,
|
||||||
|
showError: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getDerivedStateFromError(error: Error): State {
|
||||||
|
return { error, showError: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||||
|
console.error('Uncaught error:', error, errorInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
if (this.state.error && this.state.showError) {
|
||||||
|
const { name, message, stack } = this.state.error
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Alert
|
||||||
|
severity="error"
|
||||||
|
action={
|
||||||
|
<IconButton
|
||||||
|
aria-label="close"
|
||||||
|
color="inherit"
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
this.setState({ error: null, showError: false })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Link to={routes.ROOT}>
|
||||||
|
<CloseIcon fontSize="inherit" />
|
||||||
|
</Link>
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Typography variant="h2">
|
||||||
|
<pre>{name}</pre>
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h3">
|
||||||
|
<code>{message}</code>
|
||||||
|
</Typography>
|
||||||
|
<pre>{stack}</pre>
|
||||||
|
</Alert>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.props.children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ErrorBoundary
|
1
src/components/ErrorBoundary/index.ts
Normal file
1
src/components/ErrorBoundary/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './ErrorBoundary'
|
@ -15,6 +15,7 @@ import { AlertColor } from '@mui/material/Alert'
|
|||||||
import { ShellContext } from 'contexts/ShellContext'
|
import { ShellContext } from 'contexts/ShellContext'
|
||||||
import { SettingsContext } from 'contexts/SettingsContext'
|
import { SettingsContext } from 'contexts/SettingsContext'
|
||||||
import { AlertOptions } from 'models/shell'
|
import { AlertOptions } from 'models/shell'
|
||||||
|
import { ErrorBoundary } from 'components/ErrorBoundary'
|
||||||
|
|
||||||
import { Drawer } from './Drawer'
|
import { Drawer } from './Drawer'
|
||||||
import { UpgradeDialog } from './UpgradeDialog'
|
import { UpgradeDialog } from './UpgradeDialog'
|
||||||
@ -170,7 +171,10 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
|
|||||||
theme={theme}
|
theme={theme}
|
||||||
userPeerId={userPeerId}
|
userPeerId={userPeerId}
|
||||||
/>
|
/>
|
||||||
<RouteContent isDrawerOpen={isDrawerOpen}>{children}</RouteContent>
|
|
||||||
|
<RouteContent isDrawerOpen={isDrawerOpen}>
|
||||||
|
<ErrorBoundary>{children}</ErrorBoundary>
|
||||||
|
</RouteContent>
|
||||||
</Box>
|
</Box>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</ShellContext.Provider>
|
</ShellContext.Provider>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
export enum routes {
|
export enum routes {
|
||||||
ABOUT = '/about',
|
ABOUT = '/about',
|
||||||
HOME = '/home',
|
|
||||||
INDEX_HTML = '/index.html',
|
INDEX_HTML = '/index.html',
|
||||||
PUBLIC_ROOM = '/public/:roomId',
|
PUBLIC_ROOM = '/public/:roomId',
|
||||||
ROOT = '/',
|
ROOT = '/',
|
||||||
|
Loading…
Reference in New Issue
Block a user