diff --git a/web/src/components/common/ErrorBoundary.jsx b/web/src/components/common/ErrorBoundary.jsx new file mode 100644 index 00000000..3827969a --- /dev/null +++ b/web/src/components/common/ErrorBoundary.jsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { Empty, Button } from '@douyinfe/semi-ui'; +import { + IllustrationFailure, + IllustrationFailureDark, +} from '@douyinfe/semi-illustrations'; +import { withTranslation } from 'react-i18next'; + +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError() { + return { hasError: true }; + } + + componentDidCatch(error, errorInfo) { + console.error('[ErrorBoundary]', error, errorInfo); + } + + render() { + if (this.state.hasError) { + const { t } = this.props; + return ( +
+ + } + darkModeImage={ + + } + description={t('页面渲染出错,请刷新页面重试')} + /> + +
+ ); + } + return this.props.children; + } +} + +export default withTranslation()(ErrorBoundary); diff --git a/web/src/components/layout/PageLayout.jsx b/web/src/components/layout/PageLayout.jsx index 51666b5e..ca38ed50 100644 --- a/web/src/components/layout/PageLayout.jsx +++ b/web/src/components/layout/PageLayout.jsx @@ -23,6 +23,7 @@ import SiderBar from './SiderBar'; import App from '../../App'; import FooterBar from './Footer'; import { ToastContainer } from 'react-toastify'; +import ErrorBoundary from '../common/ErrorBoundary'; import React, { useContext, useEffect, useState } from 'react'; import { useIsMobile } from '../../hooks/common/useIsMobile'; import { useSidebarCollapsed } from '../../hooks/common/useSidebarCollapsed'; @@ -216,7 +217,9 @@ const PageLayout = () => { position: 'relative', }} > - + + + {!shouldHideFooter && (