Handle Google Translate DOM manipulation error scenario.
This commit is contained in:
40
src/common/components/ReloadOnError.jsx
Normal file
40
src/common/components/ReloadOnError.jsx
Normal 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,
|
||||
};
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user