[AO] Handle buildEsQuery error (such as leading wildcard) in status change (#159891)

Fixes #159079

## Summary

In the case of providing a wildcard in the search query, an error might
be generated depending on whether the related setting is enabled or not.
This PR tries to handle this error on the Alerts page for a better user
experience.

|Before|After|
|---|---|

|![image](cf74577e-10ab-4543-8135-f498dcc7cabf)|
This commit is contained in:
Maryam Saeidi 2023-06-19 16:22:28 +02:00 committed by GitHub
parent 2f0c12a00c
commit 229e8ca808
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 16 deletions

View file

@ -8,7 +8,7 @@
import React from 'react'; import React from 'react';
import { waitFor } from '@testing-library/react'; import { waitFor } from '@testing-library/react';
import { timefilterServiceMock } from '@kbn/data-plugin/public/query/timefilter/timefilter_service.mock'; import { timefilterServiceMock } from '@kbn/data-plugin/public/query/timefilter/timefilter_service.mock';
import { ObservabilityAlertSearchBarProps } from './types'; import { ObservabilityAlertSearchBarProps, Services } from './types';
import { ObservabilityAlertSearchBar } from './alert_search_bar'; import { ObservabilityAlertSearchBar } from './alert_search_bar';
import { observabilityAlertFeatureIds } from '../../config/alert_feature_ids'; import { observabilityAlertFeatureIds } from '../../config/alert_feature_ids';
import { render } from '../../utils/test_helper'; import { render } from '../../utils/test_helper';
@ -17,7 +17,10 @@ const getAlertsSearchBarMock = jest.fn();
const ALERT_SEARCH_BAR_DATA_TEST_SUBJ = 'alerts-search-bar'; const ALERT_SEARCH_BAR_DATA_TEST_SUBJ = 'alerts-search-bar';
describe('ObservabilityAlertSearchBar', () => { describe('ObservabilityAlertSearchBar', () => {
const renderComponent = (props: Partial<ObservabilityAlertSearchBarProps> = {}) => { const renderComponent = (
props: Partial<ObservabilityAlertSearchBarProps> = {},
services: Partial<Services> = {}
) => {
const observabilityAlertSearchBarProps: ObservabilityAlertSearchBarProps = { const observabilityAlertSearchBarProps: ObservabilityAlertSearchBarProps = {
appName: 'testAppName', appName: 'testAppName',
kuery: '', kuery: '',
@ -35,6 +38,7 @@ describe('ObservabilityAlertSearchBar', () => {
<div data-test-subj={ALERT_SEARCH_BAR_DATA_TEST_SUBJ} /> <div data-test-subj={ALERT_SEARCH_BAR_DATA_TEST_SUBJ} />
), ),
useToasts: jest.fn(), useToasts: jest.fn(),
...services,
}, },
...props, ...props,
}; };
@ -152,4 +156,26 @@ describe('ObservabilityAlertSearchBar', () => {
}, },
}); });
}); });
it('should show error in a toast', async () => {
const error = new Error('something is wrong in esQueryChange');
const mockedOnEsQueryChange = jest.fn().mockImplementation(() => {
throw error;
});
const mockedAddError = jest.fn();
const mockedUseToast = jest.fn().mockImplementation(() => ({
addError: mockedAddError,
}));
renderComponent(
{
onEsQueryChange: mockedOnEsQueryChange,
},
{
useToasts: mockedUseToast,
}
);
expect(mockedAddError).toHaveBeenCalledWith(error, { title: 'Invalid query string' });
});
}); });

View file

@ -22,6 +22,9 @@ const getAlertStatusQuery = (status: string): Query[] => {
? [{ query: ALERT_STATUS_QUERY[status], language: 'kuery' }] ? [{ query: ALERT_STATUS_QUERY[status], language: 'kuery' }]
: []; : [];
}; };
const toastTitle = i18n.translate('xpack.observability.alerts.searchBar.invalidQueryTitle', {
defaultMessage: 'Invalid query string',
});
export function ObservabilityAlertSearchBar({ export function ObservabilityAlertSearchBar({
appName, appName,
@ -41,18 +44,25 @@ export function ObservabilityAlertSearchBar({
const onAlertStatusChange = useCallback( const onAlertStatusChange = useCallback(
(alertStatus: AlertStatus) => { (alertStatus: AlertStatus) => {
onEsQueryChange( try {
buildEsQuery( onEsQueryChange(
{ buildEsQuery(
to: rangeTo, {
from: rangeFrom, to: rangeTo,
}, from: rangeFrom,
kuery, },
[...getAlertStatusQuery(alertStatus), ...defaultSearchQueries] kuery,
) [...getAlertStatusQuery(alertStatus), ...defaultSearchQueries]
); )
);
} catch (error) {
toasts.addError(error, {
title: toastTitle,
});
onKueryChange(DEFAULT_QUERY_STRING);
}
}, },
[kuery, defaultSearchQueries, rangeFrom, rangeTo, onEsQueryChange] [onEsQueryChange, rangeTo, rangeFrom, kuery, defaultSearchQueries, toasts, onKueryChange]
); );
useEffect(() => { useEffect(() => {
@ -83,9 +93,7 @@ export function ObservabilityAlertSearchBar({
onEsQueryChange(esQuery); onEsQueryChange(esQuery);
} catch (error) { } catch (error) {
toasts.addError(error, { toasts.addError(error, {
title: i18n.translate('xpack.observability.alerts.searchBar.invalidQueryTitle', { title: toastTitle,
defaultMessage: 'Invalid query string',
}),
}); });
onKueryChange(DEFAULT_QUERY_STRING); onKueryChange(DEFAULT_QUERY_STRING);
} }