Skip to content

Commit 008efc1

Browse files
[UI] Fix: error boundary does not allow user to navigate away from the page (#2167)
* Error boundary implementation with core component * Add Error Boundary component * Revert to main version of core Co-authored-by: Ahmed Magdy <[email protected]>
1 parent 5a0421e commit 008efc1

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed
Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,45 @@
1-
import * as React from 'react';
1+
import React, { useState, useEffect, FC } from 'react';
2+
import { useLocation } from 'react-router-dom';
23
import { ContentWrapper } from './Layout/ContentWrapper';
34
import { PageTemplate } from './Layout/PageTemplate';
4-
export default class ErrorBoundary extends React.Component<
5-
any,
6-
{ hasError: boolean; error: Error | null }
7-
> {
5+
6+
interface Props {
7+
hasError: boolean;
8+
error: Error | null;
9+
}
10+
11+
class ErrorBoundaryDetail extends React.Component<any, Props> {
812
constructor(props: any) {
913
super(props);
1014
this.state = { hasError: false, error: null };
1115
}
1216

1317
static getDerivedStateFromError(error: Error) {
14-
// Update state so the next render will show the fallback UI.
1518
return { hasError: true, error };
1619
}
1720

21+
componentDidUpdate(prevProps: Props) {
22+
if (!this.props.hasError && prevProps.hasError) {
23+
this.setState({ hasError: false });
24+
}
25+
}
26+
1827
componentDidCatch(error: Error) {
19-
// You can also log the error to an error reporting service
2028
console.error(error);
29+
this.props.setHasError(true);
2130
}
2231

2332
render() {
2433
if (this.state.hasError) {
25-
// You can render any custom fallback UI
2634
return (
27-
<PageTemplate documentTitle="Error" path={[{ label: 'Error' }]}>
35+
<PageTemplate
36+
documentTitle="Error"
37+
path={[
38+
{
39+
label: 'Error',
40+
},
41+
]}
42+
>
2843
<ContentWrapper>
2944
<h3>Something went wrong.</h3>
3045
<pre>{this.state.error?.message}</pre>
@@ -37,3 +52,25 @@ export default class ErrorBoundary extends React.Component<
3752
return this.props.children;
3853
}
3954
}
55+
56+
/** Function component wrapper as we need useEffect to set the state back to false on location changing **/
57+
const ErrorBoundary: FC<{
58+
children: React.ReactNode;
59+
}> = ({ children }) => {
60+
const [hasError, setHasError] = useState<boolean>(false);
61+
const location = useLocation();
62+
63+
useEffect(() => {
64+
if (hasError) {
65+
setHasError(false);
66+
}
67+
}, [location.key]);
68+
69+
return (
70+
<ErrorBoundaryDetail hasError={hasError} setHasError={setHasError}>
71+
{children}
72+
</ErrorBoundaryDetail>
73+
);
74+
};
75+
76+
export default ErrorBoundary;

ui-cra/src/components/ResponsiveDrawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ import EnterpriseClientProvider from '../contexts/EnterpriseClient/Provider';
2929
import { TerraformProvider } from '../contexts/Terraform';
3030
import NotificationsProvider from '../contexts/Notifications/Provider';
3131
import AppRoutes from '../routes';
32-
import ErrorBoundary from './ErrorBoundary';
3332
import { Navigation } from './Navigation';
3433
import Compose from './ProvidersCompose';
3534
import { resolver } from '../utils/link-resolver';
3635
import { ListConfigProvider, VersionProvider } from '../contexts/ListConfig';
36+
import ErrorBoundary from './ErrorBoundary';
3737

3838
const drawerWidth = 220;
3939

0 commit comments

Comments
 (0)