Improve CM error management

Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2021-04-02 15:47:53 +02:00
parent 345eef3ca4
commit 3b3637e584
10 changed files with 74 additions and 105 deletions

View File

@ -1,49 +0,0 @@
/**
*
* ErrorBoundary
*
*/
import React from 'react';
import PropTypes from 'prop-types';
class ErrorBoundary extends React.Component {
// eslint-disable-line react/prefer-stateless-function
state = { error: null, errorInfo: null };
componentDidCatch(error, errorInfo) {
this.setState({
error,
errorInfo,
});
}
render() {
const { error, errorInfo } = this.state;
if (errorInfo) {
return (
<div style={{ background: '#ffff' }}>
<h2>Something went wrong.</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{error && error.toString()}
<br />
{errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
ErrorBoundary.defaultProps = {
children: null,
};
ErrorBoundary.propTypes = {
children: PropTypes.node,
};
export default ErrorBoundary;

View File

@ -1,22 +0,0 @@
import React from 'react';
import { shallow } from 'enzyme';
import ErrorBoundary from '../index';
describe('<ErrorBoundary />', () => {
it('should not crash', () => {
shallow(<ErrorBoundary />);
});
it('should render its child', () => {
const Child = () => <div>test</div>;
const wrapper = shallow(
<ErrorBoundary>
<Child />
</ErrorBoundary>,
);
expect(wrapper.find(Child)).toHaveLength(1);
});
});

View File

@ -8,12 +8,10 @@ import React, { memo } from 'react';
import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';
import { get } from 'lodash';
import { BlockerComponent } from 'strapi-helper-plugin';
import { ErrorBoundary } from 'react-error-boundary';
import { BlockerComponent, ErrorFallback } from 'strapi-helper-plugin';
import PageTitle from '../../components/PageTitle';
import { LOGIN_LOGO } from '../../config';
import ErrorBoundary from '../ErrorBoundary';
export function PluginDispatcher(props) {
const {
@ -46,7 +44,7 @@ export function PluginDispatcher(props) {
return (
<div>
<PageTitle title={`Strapi - ${name}`} />
<ErrorBoundary>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<PluginEntryComponent
{...props}
{...blockerComponentProps}

View File

@ -79,6 +79,7 @@
"react-dnd": "^10.0.2",
"react-dnd-html5-backend": "^10.0.2",
"react-dom": "^16.9.0",
"react-error-boundary": "3.1.1",
"react-fast-compare": "^3.2.0",
"react-helmet": "^6.1.0",
"react-intl": "4.5.0",

View File

@ -27,6 +27,7 @@ const alias = [
'react-dnd',
'react-dnd-html5-backend',
'react-dom',
'react-error-boundary',
'react-fast-compare',
'react-helmet',
'react-is',

View File

@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
// https://github.com/bvaughn/react-error-boundary#usage
function ErrorFallback({ error /* resetErrorBoundary */ }) {
return (
<div style={{ background: '#ffff' }}>
<h2>Something went wrong.</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{error.message}
<br />
{error.stack}
</details>
</div>
);
}
ErrorFallback.defaultProps = {
error: { message: null },
// resetErrorBoundary: PropTypes.func,
};
ErrorFallback.propTypes = {
error: PropTypes.shape({ message: PropTypes.string }),
// resetErrorBoundary: PropTypes.func,
};
export default ErrorFallback;

View File

@ -17,6 +17,7 @@ export { default as CircleButton } from './components/CircleButton';
export { default as ContainerFluid } from './components/ContainerFluid';
export { default as ErrorBoundary } from './components/ErrorBoundary';
export { default as ExtendComponent } from './components/ExtendComponent';
export { default as ErrorFallback } from './components/ErrorFallback';
export { default as FilterButton } from './components/FilterButton';
export { default as GlobalPagination } from './components/GlobalPagination';
export { default as HeaderNav } from './components/HeaderNav';

View File

@ -1,8 +1,9 @@
import React, { memo, useMemo } from 'react';
import { Switch, Route } from 'react-router-dom';
import { ErrorBoundary } from 'react-error-boundary';
import { get } from 'lodash';
import PropTypes from 'prop-types';
import { LoadingIndicatorPage, CheckPagePermissions } from 'strapi-helper-plugin';
import { ErrorFallback, LoadingIndicatorPage, CheckPagePermissions } from 'strapi-helper-plugin';
import pluginPermissions from '../../permissions';
import { ContentTypeLayoutContext } from '../../contexts';
import { useFetchContentTypeLayout } from '../../hooks';
@ -82,31 +83,33 @@ const CollectionTypeRecursivePath = ({
));
return (
<ContentTypeLayoutContext.Provider value={layout}>
<Switch>
<Route path={`${url}/configurations/list`}>
<CheckPagePermissions permissions={pluginPermissions.collectionTypesConfigurations}>
<ListSettingsView
layout={rawContentTypeLayout}
slug={slug}
updateLayout={updateLayout}
/>
</CheckPagePermissions>
</Route>
<Route path={`${url}/configurations/edit`}>
<CheckPagePermissions permissions={pluginPermissions.collectionTypesConfigurations}>
<EditSettingsView
components={rawComponentsLayouts}
isContentTypeView
mainLayout={rawContentTypeLayout}
slug={slug}
updateLayout={updateLayout}
/>
</CheckPagePermissions>
</Route>
{routes}
</Switch>
</ContentTypeLayoutContext.Provider>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ContentTypeLayoutContext.Provider value={layout}>
<Switch>
<Route path={`${url}/configurations/list`}>
<CheckPagePermissions permissions={pluginPermissions.collectionTypesConfigurations}>
<ListSettingsView
layout={rawContentTypeLayout}
slug={slug}
updateLayout={updateLayout}
/>
</CheckPagePermissions>
</Route>
<Route path={`${url}/configurations/edit`}>
<CheckPagePermissions permissions={pluginPermissions.collectionTypesConfigurations}>
<EditSettingsView
components={rawComponentsLayouts}
isContentTypeView
mainLayout={rawContentTypeLayout}
slug={slug}
updateLayout={updateLayout}
/>
</CheckPagePermissions>
</Route>
{routes}
</Switch>
</ContentTypeLayoutContext.Provider>
</ErrorBoundary>
);
};

View File

@ -10,14 +10,14 @@ import { Flex, Padded } from '@buffetjs/core';
import isEqual from 'react-fast-compare';
import { stringify } from 'qs';
import {
PopUpWarning,
request,
CheckPermissions,
useGlobalContext,
InjectionZone,
InjectionZoneList,
PopUpWarning,
useGlobalContext,
useQueryParams,
useUser,
request,
} from 'strapi-helper-plugin';
import pluginId from '../../pluginId';
import pluginPermissions from '../../permissions';

View File

@ -16327,6 +16327,13 @@ react-dom@^16.9.0:
prop-types "^15.6.2"
scheduler "^0.19.1"
react-error-boundary@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.1.tgz#932c5ca5cbab8ec4fe37fd7b415aa5c3a47597e7"
integrity sha512-W3xCd9zXnanqrTUeViceufD3mIW8Ut29BUD+S2f0eO2XCOU8b6UrJfY46RDGe5lxCJzfe4j0yvIfh0RbTZhKJw==
dependencies:
"@babel/runtime" "^7.12.5"
react-fast-compare@^2.0.1:
version "2.0.4"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"