Handle errors in EQL search strategy (#81071)

Errors thrown by e.g. the EQL client would not be caught by the search
strategy.
This commit is contained in:
Ryland Herrick 2020-10-20 14:33:01 -05:00 committed by GitHub
parent 35404b41bb
commit cdf276cc36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 37 deletions

View file

@ -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', () => {

View file

@ -29,48 +29,53 @@ export const eqlSearchStrategyProvider = (
},
search: (request, options, context) =>
from(
new Promise<EqlSearchStrategyResponse>(async (resolve) => {
new Promise<EqlSearchStrategyResponse>(async (resolve, reject) => {
logger.debug(`_eql/search ${JSON.stringify(request.params) || request.id}`);
let promise: TransportRequestPromise<ApiResponse>;
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 });
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;
resolve({
id,
isPartial,
isRunning,
rawResponse,
});
promise = eqlClient.search(
searchParams as EqlSearchStrategyRequest['params'],
searchOptions
);
} catch (e) {
reject(e);
}
const rawResponse = await shimAbortSignal(promise, options?.abortSignal);
const { id, is_partial: isPartial, is_running: isRunning } = rawResponse.body;
resolve({
id,
isPartial,
isRunning,
rawResponse,
});
})
),
};