1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Add error boundary for page crashes

This commit is contained in:
Bill Thornton 2024-06-25 15:13:32 -04:00
parent 9186c0af41
commit 0d9a8680fb
5 changed files with 85 additions and 3 deletions

View file

@ -7,6 +7,7 @@ import { toAsyncPageRoute } from 'components/router/AsyncRoute';
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';
import { LEGACY_ADMIN_ROUTES } from './_legacyRoutes';
import ServerContentPage from 'components/ServerContentPage';
import ErrorBoundary from '../../../components/router/ErrorBoundary';
export const DASHBOARD_APP_PATHS = {
Dashboard: 'dashboard',
@ -26,7 +27,8 @@ export const DASHBOARD_APP_ROUTES: RouteObject[] = [
children: [
...ASYNC_ADMIN_ROUTES.map(toAsyncPageRoute),
...LEGACY_ADMIN_ROUTES.map(toViewManagerPageRoute)
]
],
errorElement: <ErrorBoundary pageClasses={[ 'type-interior' ]} />
},
/* NOTE: The metadata editor might deserve a dedicated app in the future */

View file

@ -6,6 +6,8 @@ import ConnectionRequired from 'components/ConnectionRequired';
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';
import { toRedirectRoute } from 'components/router/Redirect';
import ErrorBoundary from 'components/router/ErrorBoundary';
import AppLayout from '../AppLayout';
import { ASYNC_USER_ROUTES } from './asyncRoutes';
@ -29,7 +31,8 @@ export const EXPERIMENTAL_APP_ROUTES: RouteObject[] = [
path: 'video',
element: <VideoPage />
}
]
],
ErrorBoundary
},
/* Public routes */

View file

@ -5,6 +5,7 @@ import ConnectionRequired from 'components/ConnectionRequired';
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';
import { toRedirectRoute } from 'components/router/Redirect';
import ErrorBoundary from 'components/router/ErrorBoundary';
import AppLayout from '../AppLayout';
@ -23,7 +24,8 @@ export const STABLE_APP_ROUTES: RouteObject[] = [
children: [
...ASYNC_USER_ROUTES.map(toAsyncPageRoute),
...LEGACY_USER_ROUTES.map(toViewManagerPageRoute)
]
],
ErrorBoundary
},
/* Public routes */

View file

@ -0,0 +1,67 @@
import Alert from '@mui/material/Alert/Alert';
import AlertTitle from '@mui/material/AlertTitle/AlertTitle';
import Box from '@mui/material/Box/Box';
import Paper from '@mui/material/Paper/Paper';
import Typography from '@mui/material/Typography/Typography';
import classNames from 'classnames';
import React, { type FC, useEffect } from 'react';
import { useRouteError } from 'react-router-dom';
import loading from 'components/loading/loading';
import Page from 'components/Page';
interface ErrorBoundaryParams {
pageClasses?: string[]
}
const ErrorBoundary: FC<ErrorBoundaryParams> = ({
pageClasses = [ 'libraryPage' ]
}) => {
const error = useRouteError() as Error;
useEffect(() => {
loading.hide();
}, []);
return (
<Page
id='errorBoundary'
className={classNames('mainAnimatedPage', pageClasses)}
>
<Box className='content-primary'>
<Alert severity='error'>
<AlertTitle>
{error.name}
</AlertTitle>
<Typography>
{error.message}
</Typography>
{error.stack && (
<Paper
variant='outlined'
sx={{
marginTop: 1,
backgroundColor: 'transparent'
}}
>
<Box
component='pre'
sx={{
overflow: 'auto',
margin: 2,
maxHeight: '25rem' // 20 lines
}}
>
{error.stack}
</Box>
</Paper>
)}
</Alert>
</Box>
</Page>
);
};
export default ErrorBoundary;

View file

@ -41,6 +41,14 @@ export const DEFAULT_THEME_OPTIONS: ThemeOptions = {
}
},
components: {
MuiAlert: {
styleOverrides: {
message: {
// NOTE: This seems like a bug. Block content does not fill the container width.
flexGrow: 1
}
}
},
MuiButton: {
defaultProps: {
variant: 'contained'