diff --git a/src/common/components/ReloadOnError.jsx b/src/common/components/ReloadOnError.jsx
new file mode 100644
index 0000000..cd6ee39
--- /dev/null
+++ b/src/common/components/ReloadOnError.jsx
@@ -0,0 +1,40 @@
+import { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { NewRelicLoggingService } from '@edx/frontend-logging';
+
+/*
+ Error boundary component used to log caught errors and reload the page.
+*/
+export default class ReloadOnError extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { hasError: false };
+ }
+
+ static getDerivedStateFromError() {
+ // Update state so the next render will show the fallback UI.
+ return { hasError: true };
+ }
+
+ componentDidCatch(error, info) {
+ NewRelicLoggingService.logError(`${error} ${info}`);
+ }
+
+ render() {
+ if (this.state.hasError) {
+ // Reload the page so the user is not stuck with a broken app.
+ window.location.reload();
+ }
+
+ return this.props.children;
+ }
+}
+
+ReloadOnError.propTypes = {
+ children: PropTypes.node,
+};
+
+ReloadOnError.defaultProps = {
+ children: null,
+};
diff --git a/src/common/index.js b/src/common/index.js
index 3a23970..1e0f43f 100644
--- a/src/common/index.js
+++ b/src/common/index.js
@@ -1,9 +1,11 @@
import * as utils from './utils';
import PageLoading from './components/PageLoading';
+import ReloadOnError from './components/ReloadOnError';
import { configureUserAccountApiService, fetchUserAccount } from './actions';
export {
PageLoading,
+ ReloadOnError,
utils,
configureUserAccountApiService,
fetchUserAccount,
diff --git a/src/components/App.jsx b/src/components/App.jsx
index 121e50d..978f80e 100644
--- a/src/components/App.jsx
+++ b/src/components/App.jsx
@@ -22,7 +22,7 @@ import {
} from '@fortawesome/free-brands-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { fetchUserAccount } from '../common';
+import { ReloadOnError, fetchUserAccount } from '../common';
import { ConnectedProfilePage } from '../profile';
import FooterLogo from '../assets/edx-footer.png';
@@ -212,17 +212,19 @@ class App extends Component {
render() {
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
);
}
}
diff --git a/src/index.jsx b/src/index.jsx
index c327fdc..fd94553 100755
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -15,24 +15,6 @@ import messages from './i18n';
import './index.scss';
import App from './components/App';
-/*
- ARCH-904
- Attempts to protect against browser extension manipulation of the DOM which
- causes React to break. See the following link:
- https://github.com/facebook/react/issues/11538#issuecomment-417504600
-*/
-if (typeof Node === 'function' && Node.prototype) {
- const originalInsertBefore = Node.prototype.insertBefore;
- // eslint-disable-next-line func-names
- Node.prototype.insertBefore = function (newNode, referenceNode) {
- if (referenceNode && referenceNode.parentNode !== this) {
- NewRelicLoggingService.logError(`Cannot insert before a reference node from a different parent: ${newNode} ${referenceNode} ${this}`);
- return newNode;
- }
- return originalInsertBefore.apply(this, arguments); // eslint-disable-line prefer-rest-params
- };
-}
-
const apiClient = getAuthenticatedAPIClient({
appBaseUrl: configuration.BASE_URL,
authBaseUrl: configuration.LMS_BASE_URL,