From 229e8ca808b5aca07ad7cead3b64a5d63cd9c650 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Mon, 19 Jun 2023 16:22:28 +0200 Subject: [PATCH] [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](https://github.com/elastic/kibana/assets/12370520/f38e4bc7-f900-4c73-8e6e-c1989eda57ad)|![image](https://github.com/elastic/kibana/assets/12370520/cf74577e-10ab-4543-8135-f498dcc7cabf)| --- .../alert_search_bar.test.tsx | 30 ++++++++++++++-- .../alert_search_bar/alert_search_bar.tsx | 36 +++++++++++-------- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/observability/public/components/alert_search_bar/alert_search_bar.test.tsx b/x-pack/plugins/observability/public/components/alert_search_bar/alert_search_bar.test.tsx index b1a8d9137d9bf..211fc4bc47d7d 100644 --- a/x-pack/plugins/observability/public/components/alert_search_bar/alert_search_bar.test.tsx +++ b/x-pack/plugins/observability/public/components/alert_search_bar/alert_search_bar.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { waitFor } from '@testing-library/react'; 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 { observabilityAlertFeatureIds } from '../../config/alert_feature_ids'; import { render } from '../../utils/test_helper'; @@ -17,7 +17,10 @@ const getAlertsSearchBarMock = jest.fn(); const ALERT_SEARCH_BAR_DATA_TEST_SUBJ = 'alerts-search-bar'; describe('ObservabilityAlertSearchBar', () => { - const renderComponent = (props: Partial = {}) => { + const renderComponent = ( + props: Partial = {}, + services: Partial = {} + ) => { const observabilityAlertSearchBarProps: ObservabilityAlertSearchBarProps = { appName: 'testAppName', kuery: '', @@ -35,6 +38,7 @@ describe('ObservabilityAlertSearchBar', () => {
), useToasts: jest.fn(), + ...services, }, ...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' }); + }); }); diff --git a/x-pack/plugins/observability/public/components/alert_search_bar/alert_search_bar.tsx b/x-pack/plugins/observability/public/components/alert_search_bar/alert_search_bar.tsx index 3922b8eeff5cf..bf4d190837850 100644 --- a/x-pack/plugins/observability/public/components/alert_search_bar/alert_search_bar.tsx +++ b/x-pack/plugins/observability/public/components/alert_search_bar/alert_search_bar.tsx @@ -22,6 +22,9 @@ const getAlertStatusQuery = (status: string): Query[] => { ? [{ query: ALERT_STATUS_QUERY[status], language: 'kuery' }] : []; }; +const toastTitle = i18n.translate('xpack.observability.alerts.searchBar.invalidQueryTitle', { + defaultMessage: 'Invalid query string', +}); export function ObservabilityAlertSearchBar({ appName, @@ -41,18 +44,25 @@ export function ObservabilityAlertSearchBar({ const onAlertStatusChange = useCallback( (alertStatus: AlertStatus) => { - onEsQueryChange( - buildEsQuery( - { - to: rangeTo, - from: rangeFrom, - }, - kuery, - [...getAlertStatusQuery(alertStatus), ...defaultSearchQueries] - ) - ); + try { + onEsQueryChange( + buildEsQuery( + { + to: rangeTo, + from: rangeFrom, + }, + 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(() => { @@ -83,9 +93,7 @@ export function ObservabilityAlertSearchBar({ onEsQueryChange(esQuery); } catch (error) { toasts.addError(error, { - title: i18n.translate('xpack.observability.alerts.searchBar.invalidQueryTitle', { - defaultMessage: 'Invalid query string', - }), + title: toastTitle, }); onKueryChange(DEFAULT_QUERY_STRING); }