[Enterprise Search] Fix bug in Add Schema modal (#104024)

* [Enterprise Search] Fix bug in Add Schema modal

This PR fixes a bug where an error passed from the server was not rendering and was causing the UI to hang. The problem is that the `body` property was missed in the error object.

* Use default message when error response for actions.setServerField has no message

* i18n-ize default error message

* Remove TODO

Co-authored-by: Byron Hulcher <byronhulcher@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Scotty Bollinger 2021-07-02 09:25:41 -05:00 committed by GitHub
parent a434bc0fbf
commit 068112049a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 6 deletions

View file

@ -5,6 +5,8 @@
* 2.0.
*/
import { i18n } from '@kbn/i18n';
import { HttpResponse } from 'src/core/public';
import { FlashMessagesLogic } from './flash_messages_logic';
@ -31,12 +33,17 @@ interface Options {
isQueued?: boolean;
}
export const defaultErrorMessage = i18n.translate(
'xpack.enterpriseSearch.shared.flashMessages.defaultErrorMessage',
{
defaultMessage: 'An unexpected error occurred',
}
);
/**
* Converts API/HTTP errors into user-facing Flash Messages
*/
export const flashAPIErrors = (error: HttpResponse<ErrorResponse>, { isQueued }: Options = {}) => {
const defaultErrorMessage = 'An unexpected error occurred';
const errorFlashMessages: IFlashMessage[] = Array.isArray(error?.body?.attributes?.errors)
? error.body!.attributes.errors.map((message) => ({ type: 'error', message }))
: [{ type: 'error', message: error?.body?.message || defaultErrorMessage }];

View file

@ -27,6 +27,7 @@ const spyScrollTo = jest.fn();
Object.defineProperty(global.window, 'scrollTo', { value: spyScrollTo });
import { ADD, UPDATE } from '../../../../../shared/constants/operations';
import { defaultErrorMessage } from '../../../../../shared/flash_messages/handle_api_errors';
import { SchemaType } from '../../../../../shared/schema/types';
import { AppLogic } from '../../../../app_logic';
@ -390,13 +391,25 @@ describe('SchemaLogic', () => {
expect(onSchemaSetSuccessSpy).toHaveBeenCalledWith(serverResponse);
});
it('handles error', async () => {
it('handles error with message', async () => {
const onSchemaSetFormErrorsSpy = jest.spyOn(SchemaLogic.actions, 'onSchemaSetFormErrors');
http.post.mockReturnValue(Promise.reject({ message: 'this is an error' }));
// We expect body.message to be a string[] when it is present
http.post.mockReturnValue(Promise.reject({ body: { message: ['this is an error'] } }));
SchemaLogic.actions.setServerField(schema, ADD);
await nextTick();
expect(onSchemaSetFormErrorsSpy).toHaveBeenCalledWith('this is an error');
expect(onSchemaSetFormErrorsSpy).toHaveBeenCalledWith(['this is an error']);
expect(spyScrollTo).toHaveBeenCalledWith(0, 0);
});
it('handles error with no message', async () => {
const onSchemaSetFormErrorsSpy = jest.spyOn(SchemaLogic.actions, 'onSchemaSetFormErrors');
http.post.mockReturnValue(Promise.reject());
SchemaLogic.actions.setServerField(schema, ADD);
await nextTick();
expect(onSchemaSetFormErrorsSpy).toHaveBeenCalledWith([defaultErrorMessage]);
expect(spyScrollTo).toHaveBeenCalledWith(0, 0);
});
});

View file

@ -17,6 +17,7 @@ import {
setErrorMessage,
clearFlashMessages,
} from '../../../../../shared/flash_messages';
import { defaultErrorMessage } from '../../../../../shared/flash_messages/handle_api_errors';
import { HttpLogic } from '../../../../../shared/http';
import {
IndexJob,
@ -349,7 +350,9 @@ export const SchemaLogic = kea<MakeLogicType<SchemaValues, SchemaActions>>({
} catch (e) {
window.scrollTo(0, 0);
if (isAdding) {
actions.onSchemaSetFormErrors(e?.message);
// We expect body.message to be a string[] for actions.onSchemaSetFormErrors
const message: string[] = e?.body?.message || [defaultErrorMessage];
actions.onSchemaSetFormErrors(message);
} else {
flashAPIErrors(e);
}