[Search] return full IKibanaSearchResponse from fetch$ (#98268)

* return full object from fetch$

* jest

* fun-ctional tests

* jest

* functional

* test

* test

* tesssst

* Update src/plugins/data/common/search/search_source/fetch/request_error.ts

Co-authored-by: Michael Dokolin <dokmic@gmail.com>

* Update src/plugins/data/common/search/expressions/esaggs/request_handler.test.ts

Co-authored-by: Michael Dokolin <dokmic@gmail.com>

* ts

* ts

* ts

* Revert "Update src/plugins/data/common/search/search_source/fetch/request_error.ts"

This reverts commit ab182e84ed.

Co-authored-by: Michael Dokolin <dokmic@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Liza Katz 2021-04-28 21:49:47 +03:00 committed by GitHub
parent 3f46d6f8a7
commit 02ac599569
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 124 additions and 82 deletions

View file

@ -355,7 +355,7 @@ export class SearchEmbeddable
this.updateOutput({ loading: true, error: undefined }); this.updateOutput({ loading: true, error: undefined });
// Make the request, wait for the final result // Make the request, wait for the final result
const resp = await searchSource.fetch$({ const {rawResponse: resp} = await searchSource.fetch$({
sessionId: searchSessionId, sessionId: searchSessionId,
}).toPromise(); }).toPromise();

View file

@ -9,7 +9,7 @@ Fetch this source from Elasticsearch, returning an observable over the response(
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript
fetch$(options?: ISearchOptions): Observable<estypes.SearchResponse<any>>; fetch$(options?: ISearchOptions): Observable<IKibanaSearchResponse<estypes.SearchResponse<any>>>;
``` ```
## Parameters ## Parameters
@ -20,5 +20,5 @@ fetch$(options?: ISearchOptions): Observable<estypes.SearchResponse<any>>;
<b>Returns:</b> <b>Returns:</b>
`Observable<estypes.SearchResponse<any>>` `Observable<IKibanaSearchResponse<estypes.SearchResponse<any>>>`

View file

@ -233,7 +233,7 @@ export const SearchExamplesApp = ({
} }
setRequest(searchSource.getSearchRequestBody()); setRequest(searchSource.getSearchRequestBody());
const res = await searchSource.fetch$().toPromise(); const { rawResponse: res } = await searchSource.fetch$().toPromise();
setResponse(res); setResponse(res);
const message = <EuiText>Searched {res.hits.total} documents.</EuiText>; const message = <EuiText>Searched {res.hits.total} documents.</EuiText>;

View file

@ -101,7 +101,7 @@ export const getTermsBucketAgg = () =>
nestedSearchSource.setField('aggs', filterAgg); nestedSearchSource.setField('aggs', filterAgg);
const response = await nestedSearchSource const { rawResponse: response } = await nestedSearchSource
.fetch$({ .fetch$({
abortSignal, abortSignal,
sessionId: searchSessionId, sessionId: searchSessionId,

View file

@ -11,7 +11,7 @@ import type { Filter } from '../../../es_query';
import type { IndexPattern } from '../../../index_patterns'; import type { IndexPattern } from '../../../index_patterns';
import type { IAggConfigs } from '../../aggs'; import type { IAggConfigs } from '../../aggs';
import type { ISearchSource } from '../../search_source'; import type { ISearchSource } from '../../search_source';
import { searchSourceCommonMock } from '../../search_source/mocks'; import { searchSourceCommonMock, searchSourceInstanceMock } from '../../search_source/mocks';
import { handleRequest, RequestHandlerParams } from './request_handler'; import { handleRequest, RequestHandlerParams } from './request_handler';
@ -20,12 +20,20 @@ jest.mock('../../tabify', () => ({
})); }));
import { tabifyAggResponse } from '../../tabify'; import { tabifyAggResponse } from '../../tabify';
import { of } from 'rxjs';
describe('esaggs expression function - public', () => { describe('esaggs expression function - public', () => {
let mockParams: MockedKeys<RequestHandlerParams>; let mockParams: MockedKeys<RequestHandlerParams>;
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks(); jest.clearAllMocks();
searchSourceInstanceMock.fetch$ = jest.fn().mockReturnValue(
of({
rawResponse: {},
})
);
mockParams = { mockParams = {
abortSignal: (jest.fn() as unknown) as jest.Mocked<AbortSignal>, abortSignal: (jest.fn() as unknown) as jest.Mocked<AbortSignal>,
aggs: ({ aggs: ({

View file

@ -111,7 +111,7 @@ export const handleRequest = async ({
inspectorAdapters.requests?.reset(); inspectorAdapters.requests?.reset();
const response = await requestSearchSource const { rawResponse: response } = await requestSearchSource
.fetch$({ .fetch$({
abortSignal, abortSignal,
sessionId: searchSessionId, sessionId: searchSessionId,

View file

@ -20,11 +20,13 @@ describe('pollSearch', () => {
resolve({ resolve({
isRunning: false, isRunning: false,
isPartial: finishWithError, isPartial: finishWithError,
rawResponse: {},
}); });
} else { } else {
resolve({ resolve({
isRunning: true, isRunning: true,
isPartial: true, isPartial: true,
rawResponse: {},
}); });
} }
}); });

View file

@ -6,8 +6,8 @@
* Side Public License, v 1. * Side Public License, v 1.
*/ */
import type { estypes } from '@elastic/elasticsearch';
import { KbnError } from '../../../../../kibana_utils/common'; import { KbnError } from '../../../../../kibana_utils/common';
import { IKibanaSearchResponse } from '../../types';
import { SearchError } from './types'; import { SearchError } from './types';
/** /**
@ -16,9 +16,9 @@ import { SearchError } from './types';
* @param {Object} resp - optional HTTP response * @param {Object} resp - optional HTTP response
*/ */
export class RequestFailure extends KbnError { export class RequestFailure extends KbnError {
public resp?: estypes.SearchResponse<any>; public resp?: IKibanaSearchResponse;
constructor(err: SearchError | null = null, resp?: estypes.SearchResponse<any>) { constructor(err: SearchError | null = null, resp?: IKibanaSearchResponse) {
super(`Request to Elasticsearch failed: ${JSON.stringify(resp || err?.message)}`); super(`Request to Elasticsearch failed: ${JSON.stringify(resp?.rawResponse || err?.message)}`);
this.resp = resp; this.resp = resp;
} }

View file

@ -6,8 +6,8 @@
* Side Public License, v 1. * Side Public License, v 1.
*/ */
import type { estypes } from '@elastic/elasticsearch';
import { GetConfigFn } from '../../../types'; import { GetConfigFn } from '../../../types';
import { IKibanaSearchResponse } from '../../types';
/** /**
* @internal * @internal
@ -24,10 +24,7 @@ export interface FetchHandlers {
* Callback which can be used to hook into responses, modify them, or perform * Callback which can be used to hook into responses, modify them, or perform
* side effects like displaying UI errors on the client. * side effects like displaying UI errors on the client.
*/ */
onResponse: ( onResponse: (request: SearchRequest, response: IKibanaSearchResponse) => IKibanaSearchResponse;
request: SearchRequest,
response: estypes.SearchResponse<any>
) => estypes.SearchResponse<any>;
} }
export interface SearchError { export interface SearchError {

View file

@ -903,18 +903,26 @@ describe('SearchSource', () => {
expect(next).toBeCalledTimes(2); expect(next).toBeCalledTimes(2);
expect(complete).toBeCalledTimes(1); expect(complete).toBeCalledTimes(1);
expect(next.mock.calls[0]).toMatchInlineSnapshot(` expect(next.mock.calls[0]).toMatchInlineSnapshot(`
Array [ Array [
Object { Object {
"isPartial": true,
"isRunning": true,
"rawResponse": Object {
"test": 1, "test": 1,
}, },
] },
]
`); `);
expect(next.mock.calls[1]).toMatchInlineSnapshot(` expect(next.mock.calls[1]).toMatchInlineSnapshot(`
Array [ Array [
Object { Object {
"isPartial": false,
"isRunning": false,
"rawResponse": Object {
"test": 2, "test": 2,
}, },
] },
]
`); `);
}); });
@ -958,13 +966,9 @@ describe('SearchSource', () => {
expect(next).toBeCalledTimes(1); expect(next).toBeCalledTimes(1);
expect(error).toBeCalledTimes(1); expect(error).toBeCalledTimes(1);
expect(complete).toBeCalledTimes(0); expect(complete).toBeCalledTimes(0);
expect(next.mock.calls[0]).toMatchInlineSnapshot(` expect(next.mock.calls[0][0].rawResponse).toStrictEqual({
Array [ test: 1,
Object { });
"test": 1,
},
]
`);
expect(error.mock.calls[0][0]).toBe(undefined); expect(error.mock.calls[0][0]).toBe(undefined);
}); });
}); });
@ -1174,7 +1178,7 @@ describe('SearchSource', () => {
expect(fetchSub.next).toHaveBeenCalledTimes(3); expect(fetchSub.next).toHaveBeenCalledTimes(3);
expect(fetchSub.complete).toHaveBeenCalledTimes(1); expect(fetchSub.complete).toHaveBeenCalledTimes(1);
expect(fetchSub.error).toHaveBeenCalledTimes(0); expect(fetchSub.error).toHaveBeenCalledTimes(0);
expect(resp).toStrictEqual({ other: 5 }); expect(resp.rawResponse).toStrictEqual({ other: 5 });
expect(typesRegistry.get('avg').postFlightRequest).toHaveBeenCalledTimes(3); expect(typesRegistry.get('avg').postFlightRequest).toHaveBeenCalledTimes(3);
}); });

View file

@ -271,7 +271,9 @@ export class SearchSource {
* Fetch this source from Elasticsearch, returning an observable over the response(s) * Fetch this source from Elasticsearch, returning an observable over the response(s)
* @param options * @param options
*/ */
fetch$(options: ISearchOptions = {}) { fetch$(
options: ISearchOptions = {}
): Observable<IKibanaSearchResponse<estypes.SearchResponse<any>>> {
const { getConfig } = this.dependencies; const { getConfig } = this.dependencies;
const syncSearchByDefault = getConfig(UI_SETTINGS.COURIER_BATCH_SEARCHES); const syncSearchByDefault = getConfig(UI_SETTINGS.COURIER_BATCH_SEARCHES);
@ -308,7 +310,11 @@ export class SearchSource {
* @deprecated Use fetch$ instead * @deprecated Use fetch$ instead
*/ */
fetch(options: ISearchOptions = {}) { fetch(options: ISearchOptions = {}) {
return this.fetch$(options).toPromise(); return this.fetch$(options)
.toPromise()
.then((r) => {
return r.rawResponse as estypes.SearchResponse<any>;
});
} }
/** /**
@ -341,7 +347,7 @@ export class SearchSource {
* PRIVATE APIS * PRIVATE APIS
******/ ******/
private inspectSearch(s$: Observable<estypes.SearchResponse<any>>, options: ISearchOptions) { private inspectSearch(s$: Observable<IKibanaSearchResponse<any>>, options: ISearchOptions) {
const { id, title, description, adapter } = options.inspector || { title: '' }; const { id, title, description, adapter } = options.inspector || { title: '' };
const requestResponder = adapter?.start(title, { const requestResponder = adapter?.start(title, {
@ -384,7 +390,7 @@ export class SearchSource {
last(undefined, null), last(undefined, null),
tap((finalResponse) => { tap((finalResponse) => {
if (finalResponse) { if (finalResponse) {
requestResponder?.stats(getResponseInspectorStats(finalResponse, this)); requestResponder?.stats(getResponseInspectorStats(finalResponse.rawResponse, this));
requestResponder?.ok({ json: finalResponse }); requestResponder?.ok({ json: finalResponse });
} }
}), }),
@ -424,8 +430,8 @@ export class SearchSource {
); );
} }
} }
return response;
} }
return response;
} }
/** /**
@ -477,7 +483,7 @@ export class SearchSource {
} }
}); });
}), }),
map(({ rawResponse }) => onResponse(searchRequest, rawResponse)) map((response) => onResponse(searchRequest, response))
); );
} }

View file

@ -12,7 +12,7 @@ import type { IKibanaSearchResponse } from './types';
* @returns true if response had an error while executing in ES * @returns true if response had an error while executing in ES
*/ */
export const isErrorResponse = (response?: IKibanaSearchResponse) => { export const isErrorResponse = (response?: IKibanaSearchResponse) => {
return !response || (!response.isRunning && response.isPartial); return !response || !response.rawResponse || (!response.isRunning && response.isPartial);
}; };
/** /**

View file

@ -2446,7 +2446,7 @@ export class SearchSource {
createChild(options?: {}): SearchSource; createChild(options?: {}): SearchSource;
createCopy(): SearchSource; createCopy(): SearchSource;
destroy(): void; destroy(): void;
fetch$(options?: ISearchOptions): Observable<estypes.SearchResponse<any>>; fetch$(options?: ISearchOptions): Observable<IKibanaSearchResponse<estypes.SearchResponse<any>>>;
// @deprecated // @deprecated
fetch(options?: ISearchOptions): Promise<estypes.SearchResponse<any>>; fetch(options?: ISearchOptions): Promise<estypes.SearchResponse<any>>;
getField<K extends keyof SearchSourceFields>(field: K, recurse?: boolean): SearchSourceFields[K]; getField<K extends keyof SearchSourceFields>(field: K, recurse?: boolean): SearchSourceFields[K];

View file

@ -12,7 +12,7 @@ import { handleResponse } from './handle_response';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths // eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { notificationServiceMock } from '../../../../../core/public/notifications/notifications_service.mock'; import { notificationServiceMock } from '../../../../../core/public/notifications/notifications_service.mock';
import { setNotifications } from '../../services'; import { setNotifications } from '../../services';
import { SearchResponse } from 'elasticsearch'; import { IKibanaSearchResponse } from 'src/plugins/data/common';
jest.mock('@kbn/i18n', () => { jest.mock('@kbn/i18n', () => {
return { return {
@ -33,8 +33,10 @@ describe('handleResponse', () => {
test('should notify if timed out', () => { test('should notify if timed out', () => {
const request = { body: {} }; const request = { body: {} };
const response = { const response = {
timed_out: true, rawResponse: {
} as SearchResponse<any>; timed_out: true,
},
} as IKibanaSearchResponse<any>;
const result = handleResponse(request, response); const result = handleResponse(request, response);
expect(result).toBe(response); expect(result).toBe(response);
expect(notifications.toasts.addWarning).toBeCalled(); expect(notifications.toasts.addWarning).toBeCalled();
@ -46,13 +48,15 @@ describe('handleResponse', () => {
test('should notify if shards failed', () => { test('should notify if shards failed', () => {
const request = { body: {} }; const request = { body: {} };
const response = { const response = {
_shards: { rawResponse: {
failed: 1, _shards: {
total: 2, failed: 1,
successful: 1, total: 2,
skipped: 1, successful: 1,
skipped: 1,
},
}, },
} as SearchResponse<any>; } as IKibanaSearchResponse<any>;
const result = handleResponse(request, response); const result = handleResponse(request, response);
expect(result).toBe(response); expect(result).toBe(response);
expect(notifications.toasts.addWarning).toBeCalled(); expect(notifications.toasts.addWarning).toBeCalled();
@ -63,7 +67,9 @@ describe('handleResponse', () => {
test('returns the response', () => { test('returns the response', () => {
const request = {}; const request = {};
const response = {} as SearchResponse<any>; const response = {
rawResponse: {},
} as IKibanaSearchResponse<any>;
const result = handleResponse(request, response); const result = handleResponse(request, response);
expect(result).toBe(response); expect(result).toBe(response);
}); });

View file

@ -9,14 +9,15 @@
import React from 'react'; import React from 'react';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { EuiSpacer } from '@elastic/eui'; import { EuiSpacer } from '@elastic/eui';
import type { estypes } from '@elastic/elasticsearch'; import { IKibanaSearchResponse } from 'src/plugins/data/common';
import { ShardFailureOpenModalButton } from '../../ui/shard_failure_modal'; import { ShardFailureOpenModalButton } from '../../ui/shard_failure_modal';
import { toMountPoint } from '../../../../kibana_react/public'; import { toMountPoint } from '../../../../kibana_react/public';
import { getNotifications } from '../../services'; import { getNotifications } from '../../services';
import { SearchRequest } from '..'; import { SearchRequest } from '..';
export function handleResponse(request: SearchRequest, response: estypes.SearchResponse<any>) { export function handleResponse(request: SearchRequest, response: IKibanaSearchResponse) {
if (response.timed_out) { const { rawResponse } = response;
if (rawResponse.timed_out) {
getNotifications().toasts.addWarning({ getNotifications().toasts.addWarning({
title: i18n.translate('data.search.searchSource.fetch.requestTimedOutNotificationMessage', { title: i18n.translate('data.search.searchSource.fetch.requestTimedOutNotificationMessage', {
defaultMessage: 'Data might be incomplete because your request timed out', defaultMessage: 'Data might be incomplete because your request timed out',
@ -24,12 +25,12 @@ export function handleResponse(request: SearchRequest, response: estypes.SearchR
}); });
} }
if (response._shards && response._shards.failed) { if (rawResponse._shards && rawResponse._shards.failed) {
const title = i18n.translate('data.search.searchSource.fetch.shardsFailedNotificationMessage', { const title = i18n.translate('data.search.searchSource.fetch.shardsFailedNotificationMessage', {
defaultMessage: '{shardsFailed} of {shardsTotal} shards failed', defaultMessage: '{shardsFailed} of {shardsTotal} shards failed',
values: { values: {
shardsFailed: response._shards.failed, shardsFailed: rawResponse._shards.failed,
shardsTotal: response._shards.total, shardsTotal: rawResponse._shards.total,
}, },
}); });
const description = i18n.translate( const description = i18n.translate(
@ -43,7 +44,7 @@ export function handleResponse(request: SearchRequest, response: estypes.SearchR
<> <>
{description} {description}
<EuiSpacer size="s" /> <EuiSpacer size="s" />
<ShardFailureOpenModalButton request={request.body} response={response} title={title} /> <ShardFailureOpenModalButton request={request.body} response={rawResponse} title={title} />
</> </>
); );

View file

@ -144,7 +144,7 @@ describe('SearchInterceptor', () => {
describe('search', () => { describe('search', () => {
test('Observable should resolve if fetch is successful', async () => { test('Observable should resolve if fetch is successful', async () => {
const mockResponse: any = { result: 200 }; const mockResponse: any = { rawResponse: {} };
fetchMock.mockResolvedValueOnce(mockResponse); fetchMock.mockResolvedValueOnce(mockResponse);
const mockRequest: IEsSearchRequest = { const mockRequest: IEsSearchRequest = {
params: {}, params: {},
@ -233,6 +233,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: true, isPartial: true,
isRunning: false, isRunning: false,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -255,6 +256,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: false, isPartial: false,
isRunning: false, isRunning: false,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -281,6 +283,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: true, isPartial: true,
isRunning: true, isRunning: true,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -289,6 +292,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: false, isPartial: false,
isRunning: false, isRunning: false,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -325,6 +329,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: false, isPartial: false,
isRunning: false, isRunning: false,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -349,6 +354,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: true, isPartial: true,
isRunning: true, isRunning: true,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -357,6 +363,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: false, isPartial: false,
isRunning: false, isRunning: false,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -389,6 +396,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: true, isPartial: true,
isRunning: true, isRunning: true,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -433,6 +441,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: true, isPartial: true,
isRunning: true, isRunning: true,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -441,6 +450,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: false, isPartial: false,
isRunning: false, isRunning: false,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -511,7 +521,10 @@ describe('SearchInterceptor', () => {
sessionId, sessionId,
}); });
await searchInterceptor.search(mockRequest, { sessionId }).toPromise(); await searchInterceptor
.search(mockRequest, { sessionId })
.toPromise()
.catch(() => {});
expect(fetchMock.mock.calls[0][0]).toEqual( expect(fetchMock.mock.calls[0][0]).toEqual(
expect.objectContaining({ expect.objectContaining({
options: { sessionId, isStored: true, isRestore: true, strategy: 'ese' }, options: { sessionId, isStored: true, isRestore: true, strategy: 'ese' },
@ -527,7 +540,10 @@ describe('SearchInterceptor', () => {
const sessionId = 'sid'; const sessionId = 'sid';
setup(null); setup(null);
await searchInterceptor.search(mockRequest, { sessionId }).toPromise(); await searchInterceptor
.search(mockRequest, { sessionId })
.toPromise()
.catch(() => {});
expect(fetchMock.mock.calls[0][0]).toEqual( expect(fetchMock.mock.calls[0][0]).toEqual(
expect.not.objectContaining({ expect.not.objectContaining({
options: { sessionId }, options: { sessionId },
@ -548,6 +564,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: true, isPartial: true,
isRunning: true, isRunning: true,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -556,6 +573,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: false, isPartial: false,
isRunning: false, isRunning: false,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -792,6 +810,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: true, isPartial: true,
isRunning: true, isRunning: true,
rawResponse: {},
id: 1, id: 1,
}, },
}, },
@ -838,6 +857,7 @@ describe('SearchInterceptor', () => {
value: { value: {
isPartial: true, isPartial: true,
isRunning: false, isRunning: false,
rawResponse: {},
id: 1, id: 1,
}, },
}, },

View file

@ -251,7 +251,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
private registerSearchStrategy = < private registerSearchStrategy = <
SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest,
SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse SearchStrategyResponse extends IKibanaSearchResponse<any> = IEsSearchResponse
>( >(
name: string, name: string,
strategy: ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse> strategy: ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse>

View file

@ -431,7 +431,7 @@ function discoverController($route, $scope) {
}, },
}) })
.toPromise() .toPromise()
.then(onResults) .then(({ rawResponse }) => onResults(rawResponse))
.catch((error) => { .catch((error) => {
// If the request was aborted then no need to surface this error in the UI // If the request was aborted then no need to surface this error in the UI
if (error instanceof Error && error.name === 'AbortError') return; if (error instanceof Error && error.name === 'AbortError') return;

View file

@ -325,7 +325,7 @@ export class SearchEmbeddable
try { try {
// Make the request // Make the request
const resp = await searchSource const { rawResponse: resp } = await searchSource
.fetch$({ .fetch$({
abortSignal: this.abortController.signal, abortSignal: this.abortController.signal,
sessionId: searchSessionId, sessionId: searchSessionId,

View file

@ -167,9 +167,8 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
const abortController = new AbortController(); const abortController = new AbortController();
registerCancelCallback(() => abortController.abort()); registerCancelCallback(() => abortController.abort());
let resp;
try { try {
resp = await searchSource const { rawResponse: resp } = await searchSource
.fetch$({ .fetch$({
abortSignal: abortController.signal, abortSignal: abortController.signal,
sessionId: searchSessionId, sessionId: searchSessionId,
@ -182,6 +181,7 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
}, },
}) })
.toPromise(); .toPromise();
return resp;
} catch (error) { } catch (error) {
if (isSearchSourceAbortError(error)) { if (isSearchSourceAbortError(error)) {
throw new DataRequestAbortError(); throw new DataRequestAbortError();
@ -194,8 +194,6 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
}) })
); );
} }
return resp;
} }
async makeSearchSource( async makeSearchSource(

View file

@ -27,20 +27,20 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should request documents when zoomed to smaller regions showing less data', async () => { it('should request documents when zoomed to smaller regions showing less data', async () => {
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
// Allow a range of hits to account for variances in browser window size. // Allow a range of hits to account for variances in browser window size.
expect(response.hits.hits.length).to.be.within(30, 40); expect(response.hits.hits.length).to.be.within(30, 40);
}); });
it('should request clusters when zoomed to larger regions showing lots of data', async () => { it('should request clusters when zoomed to larger regions showing lots of data', async () => {
await PageObjects.maps.setView(20, -90, 2); await PageObjects.maps.setView(20, -90, 2);
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(17); expect(response.aggregations.gridSplit.buckets.length).to.equal(17);
}); });
it('should request documents when query narrows data', async () => { it('should request documents when query narrows data', async () => {
await PageObjects.maps.setAndSubmitQuery('bytes > 19000'); await PageObjects.maps.setAndSubmitQuery('bytes > 19000');
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.hits.hits.length).to.equal(75); expect(response.hits.hits.length).to.equal(75);
}); });
}); });

View file

@ -23,7 +23,7 @@ export default function ({ getPageObjects, getService }) {
it('should only fetch geo_point field and nothing else when source does not have data driven styling', async () => { it('should only fetch geo_point field and nothing else when source does not have data driven styling', async () => {
await PageObjects.maps.loadSavedMap('document example'); await PageObjects.maps.loadSavedMap('document example');
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
const firstHit = response.hits.hits[0]; const firstHit = response.hits.hits[0];
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']); expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
expect(firstHit.fields).to.only.have.keys(['geo.coordinates']); expect(firstHit.fields).to.only.have.keys(['geo.coordinates']);
@ -31,7 +31,7 @@ export default function ({ getPageObjects, getService }) {
it('should only fetch geo_point field and data driven styling fields', async () => { it('should only fetch geo_point field and data driven styling fields', async () => {
await PageObjects.maps.loadSavedMap('document example with data driven styles'); await PageObjects.maps.loadSavedMap('document example with data driven styles');
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
const firstHit = response.hits.hits[0]; const firstHit = response.hits.hits[0];
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']); expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
expect(firstHit.fields).to.only.have.keys(['bytes', 'geo.coordinates', 'hour_of_day']); expect(firstHit.fields).to.only.have.keys(['bytes', 'geo.coordinates', 'hour_of_day']);
@ -39,7 +39,7 @@ export default function ({ getPageObjects, getService }) {
it('should format date fields as epoch_millis when data driven styling is applied to a date field', async () => { it('should format date fields as epoch_millis when data driven styling is applied to a date field', async () => {
await PageObjects.maps.loadSavedMap('document example with data driven styles on date field'); await PageObjects.maps.loadSavedMap('document example with data driven styles on date field');
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
const firstHit = response.hits.hits[0]; const firstHit = response.hits.hits[0];
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']); expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
expect(firstHit.fields).to.only.have.keys(['@timestamp', 'bytes', 'geo.coordinates']); expect(firstHit.fields).to.only.have.keys(['@timestamp', 'bytes', 'geo.coordinates']);

View file

@ -83,7 +83,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should apply container state (time, query, filters) to embeddable when loaded', async () => { it('should apply container state (time, query, filters) to embeddable when loaded', async () => {
const response = await PageObjects.maps.getResponseFromDashboardPanel( const { rawResponse: response } = await PageObjects.maps.getResponseFromDashboardPanel(
'geo grid vector grid example' 'geo grid vector grid example'
); );
expect(response.aggregations.gridSplit.buckets.length).to.equal(6); expect(response.aggregations.gridSplit.buckets.length).to.equal(6);
@ -95,12 +95,12 @@ export default function ({ getPageObjects, getService }) {
await filterBar.selectIndexPattern('meta_for_geo_shapes*'); await filterBar.selectIndexPattern('meta_for_geo_shapes*');
await filterBar.addFilter('shape_name', 'is', 'alpha'); // runtime fields do not have autocomplete await filterBar.addFilter('shape_name', 'is', 'alpha'); // runtime fields do not have autocomplete
const gridResponse = await PageObjects.maps.getResponseFromDashboardPanel( const { rawResponse: gridResponse } = await PageObjects.maps.getResponseFromDashboardPanel(
'geo grid vector grid example' 'geo grid vector grid example'
); );
expect(gridResponse.aggregations.gridSplit.buckets.length).to.equal(1); expect(gridResponse.aggregations.gridSplit.buckets.length).to.equal(1);
const joinResponse = await PageObjects.maps.getResponseFromDashboardPanel( const { rawResponse: joinResponse } = await PageObjects.maps.getResponseFromDashboardPanel(
'join example', 'join example',
'meta_for_geo_shapes*.runtime_shape_name' 'meta_for_geo_shapes*.runtime_shape_name'
); );

View file

@ -141,7 +141,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should apply query to geotile_grid aggregation request', async () => { it('should apply query to geotile_grid aggregation request', async () => {
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(1); expect(response.aggregations.gridSplit.buckets.length).to.equal(1);
}); });
}); });
@ -152,7 +152,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should contain geotile_grid aggregation elasticsearch request', async () => { it('should contain geotile_grid aggregation elasticsearch request', async () => {
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(4); expect(response.aggregations.gridSplit.buckets.length).to.equal(4);
}); });
@ -204,7 +204,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should apply query to geotile_grid aggregation request', async () => { it('should apply query to geotile_grid aggregation request', async () => {
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(1); expect(response.aggregations.gridSplit.buckets.length).to.equal(1);
}); });
}); });
@ -215,7 +215,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should contain geotile_grid aggregation elasticsearch request', async () => { it('should contain geotile_grid aggregation elasticsearch request', async () => {
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(4); expect(response.aggregations.gridSplit.buckets.length).to.equal(4);
}); });
@ -244,7 +244,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should contain geotile_grid aggregation elasticsearch request', async () => { it('should contain geotile_grid aggregation elasticsearch request', async () => {
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(13); expect(response.aggregations.gridSplit.buckets.length).to.equal(13);
}); });
}); });

View file

@ -24,7 +24,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should request source clusters for destination locations', async () => { it('should request source clusters for destination locations', async () => {
const response = await PageObjects.maps.getResponse(); const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.destSplit.buckets.length).to.equal(2); expect(response.aggregations.destSplit.buckets.length).to.equal(2);
}); });

View file

@ -121,7 +121,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should not apply query to source and apply query to join', async () => { it('should not apply query to source and apply query to join', async () => {
const joinResponse = await PageObjects.maps.getResponse( const { rawResponse: joinResponse } = await PageObjects.maps.getResponse(
'meta_for_geo_shapes*.runtime_shape_name' 'meta_for_geo_shapes*.runtime_shape_name'
); );
expect(joinResponse.aggregations.join.buckets.length).to.equal(2); expect(joinResponse.aggregations.join.buckets.length).to.equal(2);
@ -138,7 +138,7 @@ export default function ({ getPageObjects, getService }) {
}); });
it('should apply query to join request', async () => { it('should apply query to join request', async () => {
const joinResponse = await PageObjects.maps.getResponse( const { rawResponse: joinResponse } = await PageObjects.maps.getResponse(
'meta_for_geo_shapes*.runtime_shape_name' 'meta_for_geo_shapes*.runtime_shape_name'
); );
expect(joinResponse.aggregations.join.buckets.length).to.equal(1); expect(joinResponse.aggregations.join.buckets.length).to.equal(1);