diff --git a/src/account-settings/delete-account/data/sagas.js b/src/account-settings/delete-account/data/sagas.js index e9590b1..30c3ce8 100644 --- a/src/account-settings/delete-account/data/sagas.js +++ b/src/account-settings/delete-account/data/sagas.js @@ -1,5 +1,4 @@ -import { put, push, call, takeEvery } from 'redux-saga/effects'; -import { logAPIErrorResponse } from '@edx/frontend-logging'; +import { put, call, takeEvery } from 'redux-saga/effects'; import { DELETE_ACCOUNT, @@ -19,8 +18,7 @@ export function* handleDeleteAccount(action) { if (typeof e.response.data === 'string') { yield put(deleteAccountFailure()); } else { - logAPIErrorResponse(e); - yield put(push('/error')); + throw e; } } } diff --git a/src/account-settings/reset-password/data/sagas.js b/src/account-settings/reset-password/data/sagas.js index ecc89b1..29fadc6 100644 --- a/src/account-settings/reset-password/data/sagas.js +++ b/src/account-settings/reset-password/data/sagas.js @@ -1,18 +1,12 @@ -import { put, call, push, takeEvery } from 'redux-saga/effects'; -import { logAPIErrorResponse } from '@edx/frontend-logging'; +import { put, call, takeEvery } from 'redux-saga/effects'; import { resetPasswordBegin, resetPasswordSuccess, RESET_PASSWORD } from './actions'; import { postResetPassword } from './service'; function* handleResetPassword(action) { - try { - yield put(resetPasswordBegin()); - const response = yield call(postResetPassword, action.payload.email); - yield put(resetPasswordSuccess(response)); - } catch (e) { - logAPIErrorResponse(e); - yield put(push('/error')); - } + yield put(resetPasswordBegin()); + const response = yield call(postResetPassword, action.payload.email); + yield put(resetPasswordSuccess(response)); } export default function* saga() { diff --git a/src/account-settings/sagas.js b/src/account-settings/sagas.js index 3e6519f..08d5c3f 100644 --- a/src/account-settings/sagas.js +++ b/src/account-settings/sagas.js @@ -1,6 +1,4 @@ import { call, put, delay, takeEvery, select, all } from 'redux-saga/effects'; -import { push } from 'connected-react-router'; -import { logAPIErrorResponse } from '@edx/frontend-logging'; // Actions import { @@ -54,9 +52,8 @@ export function* handleFetchSettings() { timeZones, })); } catch (e) { - logAPIErrorResponse(e); yield put(fetchSettingsFailure(e.message)); - yield put(push('/error')); + throw e; } } @@ -89,21 +86,15 @@ export function* handleSaveSettings(action) { if (e.fieldErrors) { yield put(saveSettingsFailure({ fieldErrors: e.fieldErrors })); } else { - logAPIErrorResponse(e); yield put(saveSettingsFailure(e.message)); - yield put(push('/error')); + throw e; } } } export function* handleFetchTimeZones(action) { - try { - const response = yield call(ApiService.getTimeZones, action.payload.country); - yield put(fetchTimeZonesSuccess(response, action.payload.country)); - } catch (e) { - logAPIErrorResponse(e); - yield put(push('/error')); - } + const response = yield call(ApiService.getTimeZones, action.payload.country); + yield put(fetchTimeZonesSuccess(response, action.payload.country)); } diff --git a/src/common/components/ReloadOnError.jsx b/src/common/components/ErrorBoundary.jsx similarity index 50% rename from src/common/components/ReloadOnError.jsx rename to src/common/components/ErrorBoundary.jsx index cd6ee39..d0d09c8 100644 --- a/src/common/components/ReloadOnError.jsx +++ b/src/common/components/ErrorBoundary.jsx @@ -1,12 +1,14 @@ -import { Component } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { NewRelicLoggingService } from '@edx/frontend-logging'; +import { logAPIErrorResponse } from '@edx/frontend-logging'; + +import ErrorPage from './ErrorPage'; /* - Error boundary component used to log caught errors and reload the page. + Error boundary component used to log caught errors and display the error page. */ -export default class ReloadOnError extends Component { +export default class ErrorBoundary extends Component { constructor(props) { super(props); this.state = { hasError: false }; @@ -18,23 +20,22 @@ export default class ReloadOnError extends Component { } componentDidCatch(error, info) { - NewRelicLoggingService.logError(`${error} ${info}`); + logAPIErrorResponse(`${error} ${info}`); } render() { if (this.state.hasError) { - // Reload the page so the user is not stuck with a broken app. - window.location.reload(); + return ; } return this.props.children; } } -ReloadOnError.propTypes = { +ErrorBoundary.propTypes = { children: PropTypes.node, }; -ReloadOnError.defaultProps = { +ErrorBoundary.defaultProps = { children: null, }; diff --git a/src/common/components/ErrorPage.jsx b/src/common/components/ErrorPage.jsx new file mode 100644 index 0000000..1d2b495 --- /dev/null +++ b/src/common/components/ErrorPage.jsx @@ -0,0 +1,42 @@ +import React, { Component } from 'react'; +import { FormattedMessage } from '@edx/frontend-i18n'; +import { Button } from '@edx/paragon'; + +export default class ErrorPage extends Component { + reload() { + window.location.reload(); + } + + render() { + return ( +
+
+
+

+ +

+
+
+
+
+
+
+
+ ); + } +} diff --git a/src/common/index.js b/src/common/index.js index 4d7b214..7ff1a09 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -1,14 +1,14 @@ import * as utils from './utils'; import Alert from './components/Alert'; import PageLoading from './components/PageLoading'; -import ReloadOnError from './components/ReloadOnError'; +import ErrorBoundary from './components/ErrorBoundary'; import SwitchContent from './components/SwitchContent'; import { configureUserAccountApiService, fetchUserAccount } from './actions'; export { Alert, + ErrorBoundary, PageLoading, - ReloadOnError, SwitchContent, utils, configureUserAccountApiService, diff --git a/src/components/App.jsx b/src/components/App.jsx index 1ae5a30..330be9f 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -17,12 +17,11 @@ import { } from '@fortawesome/free-brands-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { ReloadOnError, fetchUserAccount } from '../common'; +import { ErrorBoundary, fetchUserAccount } from '../common'; import { ConnectedAccountSettingsPage } from '../account-settings'; import FooterLogo from '../assets/edx-footer.png'; import HeaderLogo from '../assets/logo.svg'; -import ErrorPage from './ErrorPage'; import NotFoundPage from './NotFoundPage'; import messages from './App.messages'; @@ -138,7 +137,6 @@ function PageContent({
- @@ -179,7 +177,7 @@ class App extends Component { render() { return ( - + @@ -191,7 +189,7 @@ class App extends Component { - + ); } } diff --git a/src/components/ErrorPage.jsx b/src/components/ErrorPage.jsx deleted file mode 100644 index 162869d..0000000 --- a/src/components/ErrorPage.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from '@edx/frontend-i18n'; - -export default function ErrorPage() { - return ( -
-
-
-

- -

-
-
-
- ); -}