Handle Google Translate DOM manipulation error scenario.

This commit is contained in:
Douglas Hall
2019-06-05 15:25:53 -04:00
parent 899857e40e
commit 8d968e14ad
4 changed files with 56 additions and 30 deletions

View File

@@ -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,
};

View File

@@ -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,

View File

@@ -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 (
<IntlProvider locale={getLocale()} messages={getMessages()}>
<Provider store={this.props.store}>
<ConnectedRouter history={this.props.history}>
<IntlPageContent
configuration={this.props.configuration}
username={this.props.username}
avatar={this.props.avatar}
/>
</ConnectedRouter>
</Provider>
</IntlProvider>
<ReloadOnError>
<IntlProvider locale={getLocale()} messages={getMessages()}>
<Provider store={this.props.store}>
<ConnectedRouter history={this.props.history}>
<IntlPageContent
configuration={this.props.configuration}
username={this.props.username}
avatar={this.props.avatar}
/>
</ConnectedRouter>
</Provider>
</IntlProvider>
</ReloadOnError>
);
}
}

View File

@@ -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,