diff --git a/CHANGELOG.md b/CHANGELOG.md
index c93816b4d7..1cea1443ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,7 +17,7 @@ Our versioning strategy is as follows:
### 🎉 New Features & Improvements
-* `[sitecore-jss-react]`Introduce ErrorBoundary component. All rendered components are wrapped with it and it will catch client or server side errors from any of its children, display appropriate message and prevent the rest of the application from failing. It accepts and can display custom error component and loading message if it is passed as a prop to parent Placeholder. ([#1786](https://github.com/Sitecore/jss/pull/1786) [#1790](https://github.com/Sitecore/jss/pull/1790) [#1793](https://github.com/Sitecore/jss/pull/1793))
+* `[sitecore-jss-react]`Introduce ErrorBoundary component. All rendered components are wrapped with it and it will catch client or server side errors from any of its children, display appropriate message and prevent the rest of the application from failing. It accepts and can display custom error component and loading message if it is passed as a prop to parent Placeholder. ([#1786](https://github.com/Sitecore/jss/pull/1786) [#1790](https://github.com/Sitecore/jss/pull/1790) [#1793](https://github.com/Sitecore/jss/pull/1793) [#1794](https://github.com/Sitecore/jss/pull/1794))
## 22.0.0
diff --git a/packages/sitecore-jss-react/src/components/ErrorBoundary.test.tsx b/packages/sitecore-jss-react/src/components/ErrorBoundary.test.tsx
index 578e0a8dc3..be5a9fc123 100644
--- a/packages/sitecore-jss-react/src/components/ErrorBoundary.test.tsx
+++ b/packages/sitecore-jss-react/src/components/ErrorBoundary.test.tsx
@@ -4,16 +4,16 @@ import { mount } from 'enzyme';
import { spy } from 'sinon';
import ErrorBoundary from './ErrorBoundary';
import { SitecoreContextReactContext } from '../components/SitecoreContext';
-import { ComponentRendering } from '@sitecore-jss/sitecore-jss/layout';
+import { ComponentRendering, LayoutServicePageState } from '@sitecore-jss/sitecore-jss/layout';
describe('ErrorBoundary', () => {
- describe('when in page editing mode', () => {
+ describe('when in page editing or preview mode', () => {
it('Should render custom error component when custom error component is provided and error is thrown', () => {
const setContext = spy();
const testComponentProps = {
context: {
- pageEditing: true,
+ pageState: LayoutServicePageState.Preview,
},
setContext,
};
@@ -42,12 +42,55 @@ describe('ErrorBoundary', () => {
expect(rendered.find('div').text()).to.equal('This is a custom error component!');
});
- it('Should render errors message and errored component name when error is thrown', () => {
+ it('Should render errors message and errored component name when error is thrown in edit mode', () => {
const setContext = spy();
const testComponentProps = {
context: {
- pageEditing: true,
+ pageState: LayoutServicePageState.Edit,
+ },
+ setContext,
+ };
+
+ const testComponentName = 'Test component Name';
+ const rendering: ComponentRendering = { componentName: testComponentName };
+
+ const errorMessage = 'an error occured';
+ const TestErrorComponent: React.FC = () => {
+ throw Error(errorMessage);
+ };
+
+ const rendered = mount(
+
+
+
+
+
+ );
+
+ expect(rendered.html()).to.contain('class="sc-jss-placeholder-error"');
+ expect(rendered.html()).to.contain('A rendering error occurred in component');
+ expect(rendered.find('em').length).to.equal(2);
+ expect(
+ rendered
+ .find('em')
+ .at(0)
+ .text()
+ ).to.equal(testComponentName);
+ expect(
+ rendered
+ .find('em')
+ .at(1)
+ .text()
+ ).to.equal(errorMessage);
+ });
+
+ it('Should render errors message and errored component name when error is thrown in preview mode', () => {
+ const setContext = spy();
+
+ const testComponentProps = {
+ context: {
+ pageState: LayoutServicePageState.Preview,
},
setContext,
};
@@ -230,7 +273,7 @@ describe('ErrorBoundary', () => {
);
- console.log(rendered.html());
+
expect(rendered.html()).to.contain('class="sc-jss-placeholder-error"');
expect(rendered.html()).to.contain(
'There was a problem loading this section.' // eslint-disable-line
diff --git a/packages/sitecore-jss-react/src/components/ErrorBoundary.tsx b/packages/sitecore-jss-react/src/components/ErrorBoundary.tsx
index 67cb3d4a04..cfa36356b8 100644
--- a/packages/sitecore-jss-react/src/components/ErrorBoundary.tsx
+++ b/packages/sitecore-jss-react/src/components/ErrorBoundary.tsx
@@ -1,5 +1,5 @@
import React, { ReactNode, Suspense } from 'react';
-import { ComponentRendering } from '@sitecore-jss/sitecore-jss/layout';
+import { ComponentRendering, LayoutServicePageState } from '@sitecore-jss/sitecore-jss/layout';
import { withSitecoreContext } from '../enhancers/withSitecoreContext';
import { SitecoreContextValue } from './SitecoreContext';
@@ -19,7 +19,7 @@ export type ErrorBoundaryProps = {
};
class ErrorBoundary extends React.Component {
- defaultErrorMessage = 'There was a problem loading this section.'; // eslint-disable-line
+ defaultErrorMessage = 'There was a problem loading this section.';
defaultLoadingMessage = 'Loading component...';
state: { error: Error };
@@ -33,6 +33,12 @@ class ErrorBoundary extends React.Component {
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
+ if (this.showErrorDetails()) {
+ console.error(
+ `An error occurred in component ${this.props.rendering?.componentName} (${this.props.rendering?.uid}): `
+ );
+ }
+
console.error({ error, errorInfo });
}
@@ -40,12 +46,20 @@ class ErrorBoundary extends React.Component {
return process.env.NODE_ENV === 'development';
}
+ showErrorDetails(): boolean {
+ return (
+ this.isInDevMode() ||
+ this.props.sitecoreContext?.pageState === LayoutServicePageState.Edit ||
+ this.props.sitecoreContext?.pageState === LayoutServicePageState.Preview
+ );
+ }
+
render() {
if (this.state.error) {
if (this.props.customErrorComponent) {
return ;
} else {
- if (this.isInDevMode() || this.props.sitecoreContext?.pageEditing) {
+ if (this.showErrorDetails()) {
return (