Skip to content

Commit

Permalink
fix: wrap ErrorPage with IntlProvider and pass messages (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamstankiewicz authored Aug 2, 2022
1 parent 992094d commit ef8baa3
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 29 deletions.
1 change: 1 addition & 0 deletions example/ExamplePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class ExamplePage extends Component {
{this.renderAuthenticatedUser()}
<p>EXAMPLE_VAR env var came through: <strong>{getConfig().EXAMPLE_VAR}</strong></p>
<p>Visit <Link to="/authenticated">authenticated page</Link>.</p>
<p>Visit <Link to="/error_example">error page</Link>.</p>
</div>
);
}
Expand Down
3 changes: 1 addition & 2 deletions example/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from '@edx/frontend-platform/react';
import { APP_INIT_ERROR, APP_READY, initialize } from '@edx/frontend-platform';
import { subscribe } from '@edx/frontend-platform/pubSub';
import { IntlProvider } from '@edx/frontend-platform/i18n';

import './index.scss';
import ExamplePage from './ExamplePage';
Expand All @@ -33,7 +32,7 @@ subscribe(APP_READY, () => {
});

subscribe(APP_INIT_ERROR, (error) => {
ReactDOM.render(<IntlProvider><ErrorPage message={error.message} /></IntlProvider>, document.getElementById('root'));
ReactDOM.render(<ErrorPage message={error.message} />, document.getElementById('root'));
});

initialize({
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
},
"dependencies": {
"@cospired/i18n-iso-languages": "2.2.0",
"@formatjs/intl-pluralrules": "^4.3.3",
"@formatjs/intl-relativetimeformat": "^10.0.1",
"@formatjs/intl-pluralrules": "4.3.3",
"@formatjs/intl-relativetimeformat": "10.0.1",
"axios": "0.26.1",
"axios-cache-adapter": "2.7.3",
"form-urlencoded": "4.1.4",
Expand Down
25 changes: 13 additions & 12 deletions src/react/ErrorBoundary.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ import React from 'react';
import { mount } from 'enzyme';

import ErrorBoundary from './ErrorBoundary';

import { logError } from '../logging';
import { IntlProvider } from '../i18n';

jest.mock('../logging');
import { initializeMockApp } from '..';

describe('ErrorBoundary', () => {
beforeEach(() => {
let logError = jest.fn();

beforeEach(async () => {
// This is a gross hack to suppress error logs in the invalid parentSelector test
jest.spyOn(console, 'error');
global.console.error.mockImplementation(() => {});

const { loggingService } = initializeMockApp();
logError = loggingService.logError;
});

afterEach(() => {
global.console.error.mockRestore();
jest.clearAllMocks();
});

it('should render children if no error', () => {
Expand All @@ -37,15 +39,14 @@ describe('ErrorBoundary', () => {
};

const component = (
<IntlProvider locale="en" messages={{}}>
<ErrorBoundary>
<ExplodingComponent />
</ErrorBoundary>
</IntlProvider>
<ErrorBoundary>
<ExplodingComponent />
</ErrorBoundary>
);

mount(component);

expect(logError).toHaveBeenCalledTimes(1);
expect(logError).toHaveBeenCalledWith(new Error('booyah'), { stack: '\n in ExplodingComponent\n in ErrorBoundary\n in IntlProvider (created by WrapperComponent)\n in WrapperComponent' });
expect(logError).toHaveBeenCalledWith(new Error('booyah'), { stack: '\n in ExplodingComponent\n in ErrorBoundary (created by WrapperComponent)\n in WrapperComponent' });
});
});
36 changes: 25 additions & 11 deletions src/react/ErrorPage.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import React, { Component } from 'react';
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import {
Button, Container, Row, Col,
} from '@edx/paragon';

import { FormattedMessage } from '../i18n';
import { useAppEvent } from './hooks';
import {
FormattedMessage,
IntlProvider,
getMessages,
getLocale,
LOCALE_CHANGED,
} from '../i18n';

/**
* An error page that displays a generic message for unexpected errors. Also contains a "Try
Expand All @@ -13,15 +20,22 @@ import { FormattedMessage } from '../i18n';
* @memberof module:React
* @extends {Component}
*/
class ErrorPage extends Component {
function ErrorPage({
message,
}) {
const [locale, setLocale] = useState(getLocale());

useAppEvent(LOCALE_CHANGED, () => {
setLocale(getLocale());
});

/* istanbul ignore next */
reload() {
const reload = () => {
global.location.reload();
}
};

render() {
const { message } = this.props;
return (
return (
<IntlProvider locale={locale} messages={getMessages()}>
<Container fluid className="py-5 justify-content-center align-items-start text-center">
<Row>
<Col>
Expand All @@ -37,7 +51,7 @@ class ErrorPage extends Component {
<p>{message}</p>
</div>
)}
<Button onClick={this.reload}>
<Button onClick={reload}>
<FormattedMessage
id="unexpected.error.button.text"
defaultMessage="Try again"
Expand All @@ -47,8 +61,8 @@ class ErrorPage extends Component {
</Col>
</Row>
</Container>
);
}
</IntlProvider>
);
}

ErrorPage.propTypes = {
Expand Down

0 comments on commit ef8baa3

Please sign in to comment.