From 5b279dc6ecd64fe9206b7cdec10116fec880277c Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Tue, 20 Oct 2020 16:44:48 -0500 Subject: [PATCH] Handle errors in EQL search strategy (#81071) (#81235) Errors thrown by e.g. the EQL client would not be caught by the search strategy. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/search/eql_search_strategy.test.ts | 12 +++ .../server/search/eql_search_strategy.ts | 77 ++++++++++--------- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts index 5b634fe4cf26c..3360248ebb34e 100644 --- a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts @@ -98,6 +98,18 @@ describe('EQL search strategy', () => { expect(mockEqlSearch).not.toHaveBeenCalled(); expect(requestParams).toEqual(expect.objectContaining({ id: 'my-search-id' })); }); + + it('emits an error if the client throws', async () => { + expect.assertions(1); + mockEqlSearch.mockReset().mockRejectedValueOnce(new Error('client error')); + const eqlSearch = await eqlSearchStrategyProvider(mockLogger); + eqlSearch.search({ options, params }, {}, mockContext).subscribe( + () => {}, + (err) => { + expect(err).toEqual(new Error('client error')); + } + ); + }); }); describe('arguments', () => { diff --git a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts index a7ca999699e23..f8dd1dca740b7 100644 --- a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts @@ -29,48 +29,53 @@ export const eqlSearchStrategyProvider = ( }, search: (request, options, context) => from( - new Promise(async (resolve) => { + new Promise(async (resolve, reject) => { logger.debug(`_eql/search ${JSON.stringify(request.params) || request.id}`); let promise: TransportRequestPromise; - const eqlClient = context.core.elasticsearch.client.asCurrentUser.eql; - const uiSettingsClient = await context.core.uiSettings.client; - const asyncOptions = getAsyncOptions(); - const searchOptions = toSnakeCase({ ...request.options }); - if (request.id) { - promise = eqlClient.get( - { - id: request.id, - ...toSnakeCase(asyncOptions), - }, - searchOptions - ); - } else { - const { ignoreThrottled, ignoreUnavailable } = await getDefaultSearchParams( - uiSettingsClient - ); - const searchParams = toSnakeCase({ - ignoreThrottled, - ignoreUnavailable, - ...asyncOptions, - ...request.params, - }); + try { + const eqlClient = context.core.elasticsearch.client.asCurrentUser.eql; + const uiSettingsClient = await context.core.uiSettings.client; + const asyncOptions = getAsyncOptions(); + const searchOptions = toSnakeCase({ ...request.options }); - promise = eqlClient.search( - searchParams as EqlSearchStrategyRequest['params'], - searchOptions - ); - } + if (request.id) { + promise = eqlClient.get( + { + id: request.id, + ...toSnakeCase(asyncOptions), + }, + searchOptions + ); + } else { + const { ignoreThrottled, ignoreUnavailable } = await getDefaultSearchParams( + uiSettingsClient + ); + const searchParams = toSnakeCase({ + ignoreThrottled, + ignoreUnavailable, + ...asyncOptions, + ...request.params, + }); + + promise = eqlClient.search( + searchParams as EqlSearchStrategyRequest['params'], + searchOptions + ); + } - const rawResponse = await shimAbortSignal(promise, options?.abortSignal); - const { id, is_partial: isPartial, is_running: isRunning } = rawResponse.body; + const rawResponse = await shimAbortSignal(promise, options?.abortSignal); + const { id, is_partial: isPartial, is_running: isRunning } = rawResponse.body; - resolve({ - id, - isPartial, - isRunning, - rawResponse, - }); + resolve({ + id, + isPartial, + isRunning, + rawResponse, + }); + } catch (e) { + reject(e); + } }) ), };