feat: use error boundary lib and setup fallback component (#3970)

* feat: use error boundary lib and setup fallback component

* feat: move text to translations
This commit is contained in:
Yunus M 2023-11-15 16:46:20 +05:30 committed by GitHub
parent f2f89eb38b
commit 37f61ebe60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 148 additions and 46 deletions

View File

@ -80,6 +80,7 @@
"react-dnd-html5-backend": "16.0.1", "react-dnd-html5-backend": "16.0.1",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-drag-listview": "2.0.0", "react-drag-listview": "2.0.0",
"react-error-boundary": "4.0.11",
"react-force-graph": "^1.43.0", "react-force-graph": "^1.43.0",
"react-grid-layout": "^1.3.4", "react-grid-layout": "^1.3.4",
"react-helmet-async": "1.3.0", "react-helmet-async": "1.3.0",

View File

@ -3,5 +3,7 @@
"see_error_in_trace_graph": "See the error in trace graph", "see_error_in_trace_graph": "See the error in trace graph",
"stack_trace": "Stacktrace", "stack_trace": "Stacktrace",
"older": "Older", "older": "Older",
"newer": "Newer" "newer": "Newer",
"something_went_wrong": "Oops !!! Something went wrong",
"contact_if_issue_exists": "Don't worry, our team is here to help. Please contact support if the issue persists."
} }

View File

@ -6,7 +6,9 @@ import Header from 'container/Header';
import SideNav from 'container/SideNav'; import SideNav from 'container/SideNav';
import TopNav from 'container/TopNav'; import TopNav from 'container/TopNav';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { ReactNode, useEffect, useMemo, useRef } from 'react'; import { ReactNode, useEffect, useMemo, useRef } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { Helmet } from 'react-helmet-async'; import { Helmet } from 'react-helmet-async';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useQueries } from 'react-query'; import { useQueries } from 'react-query';
@ -203,12 +205,15 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
{isToDisplayLayout && <Header />} {isToDisplayLayout && <Header />}
<Layout> <Layout>
{isToDisplayLayout && !renderFullScreen && <SideNav />} {isToDisplayLayout && !renderFullScreen && <SideNav />}
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<LayoutContent> <LayoutContent>
<ChildrenContainer> <ChildrenContainer>
{isToDisplayLayout && !renderFullScreen && <TopNav />} {isToDisplayLayout && !renderFullScreen && <TopNav />}
{children} {children}
</ChildrenContainer> </ChildrenContainer>
</LayoutContent> </LayoutContent>
</ErrorBoundary>
</Layout> </Layout>
</Layout> </Layout>
); );

View File

@ -1,5 +1,7 @@
import { FeatureKeys } from 'constants/features'; import { FeatureKeys } from 'constants/features';
import useFeatureFlag from 'hooks/useFeatureFlag'; import useFeatureFlag from 'hooks/useFeatureFlag';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { ErrorBoundary } from 'react-error-boundary';
import ServiceMetrics from './ServiceMetrics'; import ServiceMetrics from './ServiceMetrics';
import ServiceTraces from './ServiceTraces'; import ServiceTraces from './ServiceTraces';
@ -10,9 +12,11 @@ function Services(): JSX.Element {
?.active; ?.active;
return ( return (
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<Container> <Container>
{isSpanMetricEnabled ? <ServiceMetrics /> : <ServiceTraces />} {isSpanMetricEnabled ? <ServiceMetrics /> : <ServiceTraces />}
</Container> </Container>
</ErrorBoundary>
); );
} }

View File

@ -3,7 +3,9 @@ import 'styles.scss';
import AppRoutes from 'AppRoutes'; import AppRoutes from 'AppRoutes';
import { ThemeProvider } from 'hooks/useDarkMode'; import { ThemeProvider } from 'hooks/useDarkMode';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { ErrorBoundary } from 'react-error-boundary';
import { HelmetProvider } from 'react-helmet-async'; import { HelmetProvider } from 'react-helmet-async';
import { QueryClient, QueryClientProvider } from 'react-query'; import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools'; import { ReactQueryDevtools } from 'react-query/devtools';
@ -24,6 +26,7 @@ if (container) {
const root = createRoot(container); const root = createRoot(container);
root.render( root.render(
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<HelmetProvider> <HelmetProvider>
<ThemeProvider> <ThemeProvider>
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
@ -35,6 +38,8 @@ if (container) {
)} )}
</QueryClientProvider> </QueryClientProvider>
</ThemeProvider> </ThemeProvider>
</HelmetProvider>, </HelmetProvider>
,
</ErrorBoundary>,
); );
} }

View File

@ -0,0 +1,16 @@
.error-boundary-fallback-container {
width: 100%;
.actionBtn {
display: flex;
align-items: center;
gap: 4px;
}
.title,
.actions {
display: flex;
align-items: center;
gap: 8px;
}
}

View File

@ -0,0 +1,54 @@
import './ErrorBoundaryFallback.styles.scss';
import { BugOutlined, UndoOutlined } from '@ant-design/icons';
import { Button, Card, Typography } from 'antd';
import Slack from 'container/SideNav/Slack';
import { useTranslation } from 'react-i18next';
function ErrorBoundaryFallback(): JSX.Element {
const { t } = useTranslation(['errorDetails']);
const onClickSlackHandler = (): void => {
window.open('https://signoz.io/slack', '_blank');
};
const handleReload = (): void => {
window.location.reload();
};
return (
<Card size="small" className="error-boundary-fallback-container">
<div className="title">
<BugOutlined />
<Typography.Title type="danger" level={4} style={{ margin: 0 }}>
{t('something_went_wrong')}
</Typography.Title>
</div>
<>
<p>{t('contact_if_issue_exists')}</p>
<div className="actions">
<Button
className="actionBtn"
type="default"
onClick={handleReload}
icon={<UndoOutlined />}
>
Reload
</Button>
<Button
className="actionBtn"
type="default"
onClick={onClickSlackHandler}
icon={<Slack />}
>
&nbsp; Support
</Button>
</div>
</>
</Card>
);
}
export default ErrorBoundaryFallback;

View File

@ -3,13 +3,15 @@ import ExplorerCard from 'components/ExplorerCard/ExplorerCard';
import LogExplorerQuerySection from 'container/LogExplorerQuerySection'; import LogExplorerQuerySection from 'container/LogExplorerQuerySection';
import LogsExplorerViews from 'container/LogsExplorerViews'; import LogsExplorerViews from 'container/LogsExplorerViews';
import LogsTopNav from 'container/LogsTopNav'; import LogsTopNav from 'container/LogsTopNav';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { ErrorBoundary } from 'react-error-boundary';
import { DataSource } from 'types/common/queryBuilder'; import { DataSource } from 'types/common/queryBuilder';
import { WrapperStyled } from './styles'; import { WrapperStyled } from './styles';
function LogsExplorer(): JSX.Element { function LogsExplorer(): JSX.Element {
return ( return (
<> <ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<LogsTopNav /> <LogsTopNav />
<WrapperStyled> <WrapperStyled>
<Row gutter={[0, 16]}> <Row gutter={[0, 16]}>
@ -23,7 +25,7 @@ function LogsExplorer(): JSX.Element {
</Col> </Col>
</Row> </Row>
</WrapperStyled> </WrapperStyled>
</> </ErrorBoundary>
); );
} }

View File

@ -9,7 +9,9 @@ import TraceTable from 'container/Trace/TraceTable';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import getStep from 'lib/getStep'; import getStep from 'lib/getStep';
import history from 'lib/history'; import history from 'lib/history';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { MouseEventHandler, useCallback, useEffect, useState } from 'react'; import { MouseEventHandler, useCallback, useEffect, useState } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { connect, useDispatch, useSelector } from 'react-redux'; import { connect, useDispatch, useSelector } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux'; import { bindActionCreators, Dispatch } from 'redux';
import { ThunkDispatch } from 'redux-thunk'; import { ThunkDispatch } from 'redux-thunk';
@ -144,7 +146,7 @@ function Trace({
); );
return ( return (
<> <ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<Search /> <Search />
<Container> <Container>
<div> <div>
@ -167,7 +169,7 @@ function Trace({
</Card> </Card>
</RightContainer> </RightContainer>
</Container> </Container>
</> </ErrorBoundary>
); );
} }

View File

@ -13,7 +13,9 @@ import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange'; import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import history from 'lib/history'; import history from 'lib/history';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { useCallback, useEffect, useMemo } from 'react'; import { useCallback, useEffect, useMemo } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { Dashboard } from 'types/api/dashboard/getAll'; import { Dashboard } from 'types/api/dashboard/getAll';
import { DataSource } from 'types/common/queryBuilder'; import { DataSource } from 'types/common/queryBuilder';
import { generateExportToDashboardLink } from 'utils/dashboard/generateExportToDashboardLink'; import { generateExportToDashboardLink } from 'utils/dashboard/generateExportToDashboardLink';
@ -168,6 +170,7 @@ function TracesExplorer(): JSX.Element {
]); ]);
return ( return (
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<> <>
<ExplorerCard sourcepage={DataSource.TRACES}> <ExplorerCard sourcepage={DataSource.TRACES}>
<QuerySection /> <QuerySection />
@ -190,6 +193,7 @@ function TracesExplorer(): JSX.Element {
/> />
</Container> </Container>
</> </>
</ErrorBoundary>
); );
} }

View File

@ -12733,6 +12733,13 @@ react-draggable@^4.0.0, react-draggable@^4.0.3:
clsx "^1.1.1" clsx "^1.1.1"
prop-types "^15.8.1" prop-types "^15.8.1"
react-error-boundary@4.0.11:
version "4.0.11"
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-4.0.11.tgz#36bf44de7746714725a814630282fee83a7c9a1c"
integrity sha512-U13ul67aP5DOSPNSCWQ/eO0AQEYzEFkVljULQIjMV0KlffTAhxuDoBKdO0pb/JZ8mDhMKFZ9NZi0BmLGUiNphw==
dependencies:
"@babel/runtime" "^7.12.5"
react-fast-compare@^3.2.0: react-fast-compare@^3.2.0:
version "3.2.2" version "3.2.2"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49"