Merge pull request #79 from edx/van-281/handle-500-on-register-page
Handle 500 api response
This commit is contained in:
@@ -1,47 +1,55 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { Alert } from '@edx/paragon';
|
||||
|
||||
const hasNoErrors = (userErrors) => (
|
||||
userErrors.every((errorList) => (!errorList[0]))
|
||||
);
|
||||
import { INTERNAL_SERVER_ERROR } from '../login/data/constants';
|
||||
import messages from './messages';
|
||||
|
||||
const RegistrationFailureMessage = (props) => {
|
||||
const errorMessage = props.errors;
|
||||
const { errorCode } = props.errors;
|
||||
const userErrors = [];
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
|
||||
}, [props.submitCount]);
|
||||
|
||||
Object.keys(errorMessage).forEach((key) => {
|
||||
const errors = errorMessage[key];
|
||||
const errorList = errors.map((error) => (
|
||||
(error.user_message) ? (
|
||||
<li key={error} className="text-left">
|
||||
{error.user_message}
|
||||
let serverError;
|
||||
switch (errorCode) {
|
||||
case INTERNAL_SERVER_ERROR:
|
||||
serverError = (
|
||||
<li key={INTERNAL_SERVER_ERROR} className="text-left">
|
||||
{props.intl.formatMessage(messages['registration.request.server.error'])}
|
||||
</li>
|
||||
) : null
|
||||
));
|
||||
userErrors.push(errorList);
|
||||
});
|
||||
);
|
||||
userErrors.push(serverError);
|
||||
break;
|
||||
|
||||
default:
|
||||
Object.keys(errorMessage).forEach((key) => {
|
||||
const errors = errorMessage[key];
|
||||
const errorList = errors.map((error) => (
|
||||
(error.user_message) ? (
|
||||
<li key={error} className="text-left">
|
||||
{error.user_message}
|
||||
</li>
|
||||
) : null
|
||||
));
|
||||
userErrors.push(errorList);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
hasNoErrors(userErrors) ? null : (
|
||||
!userErrors.length ? null : (
|
||||
<Alert variant="danger">
|
||||
<Alert.Heading>
|
||||
<FormattedMessage
|
||||
id="registration.request.failure.header.description.message"
|
||||
defaultMessage="We couldn't create your account."
|
||||
description="error message when registration failure."
|
||||
/>
|
||||
{props.intl.formatMessage(messages['registration.request.failure.header'])}
|
||||
</Alert.Heading>
|
||||
<div>
|
||||
<ul>
|
||||
{userErrors}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
{userErrors}
|
||||
</ul>
|
||||
|
||||
</Alert>
|
||||
)
|
||||
);
|
||||
@@ -56,8 +64,10 @@ RegistrationFailureMessage.propTypes = {
|
||||
errors: PropTypes.shape({
|
||||
email: PropTypes.array,
|
||||
username: PropTypes.array,
|
||||
errorCode: PropTypes.string,
|
||||
}),
|
||||
submitCount: PropTypes.number,
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export default RegistrationFailureMessage;
|
||||
export default injectIntl(RegistrationFailureMessage);
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
getRegistrationForm,
|
||||
registerRequest,
|
||||
} from './service';
|
||||
import { INTERNAL_SERVER_ERROR } from '../../login/data/constants';
|
||||
|
||||
export function* handleNewUserRegistration(action) {
|
||||
try {
|
||||
@@ -39,6 +40,8 @@ export function* handleNewUserRegistration(action) {
|
||||
const statusCodes = [400, 409, 403];
|
||||
if (e.response && statusCodes.includes(e.response.status)) {
|
||||
yield put(registerNewUserFailure(e.response.data));
|
||||
} else {
|
||||
yield put(registerNewUserFailure({ errorCode: INTERNAL_SERVER_ERROR }));
|
||||
}
|
||||
logError(e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { runSaga } from 'redux-saga';
|
||||
|
||||
import { camelCaseObject } from '@edx/frontend-platform';
|
||||
import * as actions from '../actions';
|
||||
import {
|
||||
fetchRealtimeValidations,
|
||||
@@ -188,6 +189,32 @@ describe('handleNewUserRegistration', () => {
|
||||
registerRequest.mockClear();
|
||||
});
|
||||
|
||||
it('should handle 500 error code', async () => {
|
||||
const registerErrorResponse = {
|
||||
response: {
|
||||
status: 500,
|
||||
data: {
|
||||
errorCode: 'internal-server-error',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const registerRequest = jest.spyOn(api, 'registerRequest').mockImplementation(() => Promise.reject(registerErrorResponse));
|
||||
|
||||
const dispatched = [];
|
||||
await runSaga(
|
||||
{ dispatch: (action) => dispatched.push(action) },
|
||||
handleNewUserRegistration,
|
||||
params,
|
||||
);
|
||||
|
||||
expect(dispatched).toEqual([
|
||||
actions.registerNewUserBegin(),
|
||||
actions.registerNewUserFailure(camelCaseObject(registerErrorResponse.response.data)),
|
||||
]);
|
||||
registerRequest.mockClear();
|
||||
});
|
||||
|
||||
it('should call service and dispatch error action', async () => {
|
||||
const loginErrorResponse = {
|
||||
response: {
|
||||
|
||||
@@ -116,6 +116,16 @@ const messages = defineMessages({
|
||||
defaultMessage: '(optional)',
|
||||
description: 'Text that appears with optional field labels',
|
||||
},
|
||||
'registration.request.server.error': {
|
||||
id: 'registration.request.server.error',
|
||||
defaultMessage: 'An error has occurred. Try refreshing the page, or check your Internet connection.',
|
||||
description: 'error message on server error.',
|
||||
},
|
||||
'registration.request.failure.header': {
|
||||
id: 'registration.request.failure.header',
|
||||
defaultMessage: 'We couldn\'t create your account.',
|
||||
description: 'error message when registration failure.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -9,7 +9,9 @@ import * as analytics from '@edx/frontend-platform/analytics';
|
||||
|
||||
import RegistrationPage from '../RegistrationPage';
|
||||
import { RenderInstitutionButton } from '../../common-components';
|
||||
import RegistrationFailureMessage from '../RegistrationFailure';
|
||||
import { PENDING_STATE } from '../../data/constants';
|
||||
import { INTERNAL_SERVER_ERROR } from '../../login/data/constants';
|
||||
import { fetchRegistrationForm, fetchRealtimeValidations, registerNewUser } from '../data/actions';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
@@ -18,6 +20,7 @@ analytics.sendTrackEvent = jest.fn();
|
||||
analytics.sendPageEvent = jest.fn();
|
||||
|
||||
const IntlRegistrationPage = injectIntl(RegistrationPage);
|
||||
const IntlRegistrationFailure = injectIntl(RegistrationFailureMessage);
|
||||
const mockStore = configureStore();
|
||||
|
||||
describe('./RegistrationPage.js', () => {
|
||||
@@ -326,6 +329,19 @@ describe('./RegistrationPage.js', () => {
|
||||
expect(tree.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should match internal server error message', () => {
|
||||
props = {
|
||||
errors: {
|
||||
errorCode: INTERNAL_SERVER_ERROR,
|
||||
},
|
||||
};
|
||||
|
||||
const registrationPage = mount(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
expect(registrationPage.find('div.alert-heading').length).toEqual(1);
|
||||
const expectedMessage = 'We couldn\'t create your account.An error has occurred. Try refreshing the page, or check your Internet connection.';
|
||||
expect(registrationPage.find('div.alert').first().text()).toEqual(expectedMessage);
|
||||
});
|
||||
|
||||
it('should match pending button state snapshot', () => {
|
||||
store = mockStore({
|
||||
...initialState,
|
||||
|
||||
@@ -976,24 +976,20 @@ exports[`./RegistrationPage.js should show error message on 409 1`] = `
|
||||
<div
|
||||
className="alert-heading h4"
|
||||
>
|
||||
<span>
|
||||
We couldn't create your account.
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
<li
|
||||
className="text-left"
|
||||
>
|
||||
It looks like test@gmail.com belongs to an existing account. Try again with a different email address.
|
||||
</li>
|
||||
<li
|
||||
className="text-left"
|
||||
>
|
||||
It looks like test belongs to an existing account. Try again with a different username.
|
||||
</li>
|
||||
</ul>
|
||||
We couldn't create your account.
|
||||
</div>
|
||||
<ul>
|
||||
<li
|
||||
className="text-left"
|
||||
>
|
||||
It looks like test@gmail.com belongs to an existing account. Try again with a different email address.
|
||||
</li>
|
||||
<li
|
||||
className="text-left"
|
||||
>
|
||||
It looks like test belongs to an existing account. Try again with a different username.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className="text-left"
|
||||
|
||||
Reference in New Issue
Block a user