remove unneeded usages of isErrorResponse (#164609)

`data.search` uses
[poll_search](https://github.com/elastic/kibana/blob/main/src/plugins/data/common/search/poll_search.ts)
to fetch data. `poll_search` checks for `isErrorResponse` and throws
when`isErrorResponse` is true. **Note** `searchSource.search` uses
`data.search` to perform searches.

```javascript
   return from(search()).pipe(
      expand(() => {
        const elapsedTime = Date.now() - startTime;
        return timer(getPollInterval(elapsedTime)).pipe(switchMap(search));
      }),
      tap((response) => {
        if (isErrorResponse(response)) {
          throw response ? new Error('Received partial response') : new AbortError();
        }
      }),
      takeWhile<Response>(isPartialResponse, true),
      takeUntil<Response>(aborted$)
    );
```

Subscribers to `data.search` and `searchSource.search` do not need to
check for `isErrorResponse` in `next`. `poll_search` has already thrown
then the response is `isErrorResponse` so these checks are dead code
blocks that are never executed.

This PR removes these dead code blocks. Breaking this change out of
https://github.com/elastic/kibana/pull/164506 so that it can be reviewed
in isolated.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2023-08-28 11:40:26 -06:00 committed by GitHub
parent 5724d01536
commit 0113eb74c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 56 additions and 257 deletions

View file

@ -30,7 +30,6 @@ import {
DataPublicPluginStart,
IKibanaSearchResponse,
isCompleteResponse,
isErrorResponse,
} from '@kbn/data-plugin/public';
import { SearchResponseWarning } from '@kbn/data-plugin/public/search/types';
import type { DataView, DataViewField } from '@kbn/data-views-plugin/public';
@ -247,9 +246,6 @@ export const SearchExamplesApp = ({
text: toMountPoint(res.warning),
});
}
} else if (isErrorResponse(res)) {
// TODO: Make response error status clearer
notifications.toasts.addDanger('An error has occurred');
}
},
error: (e) => {
@ -401,10 +397,6 @@ export const SearchExamplesApp = ({
title: 'Query result',
text: 'Query finished',
});
} else if (isErrorResponse(res)) {
setIsLoading(false);
// TODO: Make response error status clearer
notifications.toasts.addWarning('An error has occurred');
}
},
error: (e) => {

View file

@ -40,7 +40,6 @@ import {
IEsSearchRequest,
IEsSearchResponse,
isCompleteResponse,
isErrorResponse,
QueryState,
SearchSessionState,
} from '@kbn/data-plugin/public';
@ -724,8 +723,6 @@ function doSearch(
title: 'Query result',
text: mountReactNode(message),
});
} else if (isErrorResponse(res)) {
notifications.toasts.addWarning('An error has occurred');
}
}),
map((res) => ({ response: res, request: req, tookMs: performance.now() - startTs })),

View file

@ -27,7 +27,6 @@ import {
DataPublicPluginStart,
IKibanaSearchResponse,
isCompleteResponse,
isErrorResponse,
} from '@kbn/data-plugin/public';
import {
SQL_SEARCH_STRATEGY,
@ -70,10 +69,6 @@ export const SqlSearchExampleApp = ({ notifications, data }: SearchExamplesAppDe
if (isCompleteResponse(res)) {
setIsLoading(false);
setResponse(res);
} else if (isErrorResponse(res)) {
setIsLoading(false);
setResponse(res);
notifications.toasts.addDanger('An error has occurred');
}
},
error: (e) => {

View file

@ -1105,32 +1105,6 @@ describe('SearchSource', () => {
expect(complete2).toBeCalledTimes(1);
expect(searchSourceDependencies.search).toHaveBeenCalledTimes(1);
});
test('should emit error on empty response', async () => {
searchSourceDependencies.search = mockSearchMethod = jest
.fn()
.mockReturnValue(
of({ rawResponse: { test: 1 }, isPartial: true, isRunning: true }, undefined)
);
searchSource = new SearchSource({ index: indexPattern }, searchSourceDependencies);
const options = {};
const next = jest.fn();
const error = jest.fn();
const complete = jest.fn();
const res$ = searchSource.fetch$(options);
res$.subscribe({ next, error, complete });
await firstValueFrom(res$).catch((_) => {});
expect(next).toBeCalledTimes(1);
expect(error).toBeCalledTimes(1);
expect(complete).toBeCalledTimes(0);
expect(next.mock.calls[0][0].rawResponse).toStrictEqual({
test: 1,
});
expect(error.mock.calls[0][0]).toBe(undefined);
});
});
describe('inspector', () => {

View file

@ -106,7 +106,6 @@ import { getRequestInspectorStats, getResponseInspectorStats } from './inspect';
import {
getEsQueryConfig,
IKibanaSearchResponse,
isErrorResponse,
isPartialResponse,
isCompleteResponse,
UI_SETTINGS,
@ -547,9 +546,7 @@ export class SearchSource {
// For testing timeout messages in UI, uncomment the next line
// response.rawResponse.timed_out = true;
return new Observable<IKibanaSearchResponse<unknown>>((obs) => {
if (isErrorResponse(response)) {
obs.error(response);
} else if (isPartialResponse(response)) {
if (isPartialResponse(response)) {
obs.next(this.postFlightTransform(response));
} else {
if (!this.hasPostFlightRequests()) {

View file

@ -7,7 +7,7 @@
import { cloneDeep, get } from 'lodash';
import { useRef, useCallback, useMemo } from 'react';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/public';
import { isCompleteResponse } from '@kbn/data-plugin/public';
import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
import { createRandomSamplerWrapper } from '@kbn/ml-random-sampler-utils';
@ -110,8 +110,6 @@ export function useCategorizeRequest() {
next: (result) => {
if (isCompleteResponse(result)) {
resolve(processCategoryResults(result, field, unwrap));
} else if (isErrorResponse(result)) {
reject(result);
} else {
// partial results
// Ignore partial results for now.

View file

@ -6,11 +6,7 @@
*/
import { useCallback, useRef, useState } from 'react';
import {
type IKibanaSearchResponse,
isCompleteResponse,
isErrorResponse,
} from '@kbn/data-plugin/common';
import { type IKibanaSearchResponse, isCompleteResponse } from '@kbn/data-plugin/common';
import { tap } from 'rxjs/operators';
import { useAiopsAppContext } from './use_aiops_app_context';
@ -38,8 +34,6 @@ export function useCancellableSearch() {
if (isCompleteResponse(result)) {
setIsFetching(false);
resolve(result);
} else if (isErrorResponse(result)) {
reject(result);
} else {
// partial results
// Ignore partial results for now.

View file

@ -12,7 +12,7 @@ import { useDispatch } from 'react-redux';
import { Subscription } from 'rxjs';
import type { DataView } from '@kbn/data-views-plugin/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import type {
Inspect,
PaginationInputPaginated,
@ -32,8 +32,6 @@ import type { RunTimeMappings } from '../../store/sourcerer/model';
import { TimelineEventsQueries } from '../../../../common/search_strategy';
import type { KueryFilterQueryKind } from '../../../../common/types';
import type { ESQuery } from '../../../../common/typed_json';
import { useAppToasts } from '../../hooks/use_app_toasts';
import { ERROR_TIMELINE_EVENTS } from './translations';
import type { AlertWorkflowStatus } from '../../types';
import { getSearchTransactionName, useStartTransaction } from '../../lib/apm/use_start_transaction';
export type InspectResponse = Inspect & { response: string[] };
@ -220,7 +218,6 @@ export const useTimelineEventsHandler = ({
loadPage: wrappedLoadPage,
updatedAt: 0,
});
const { addWarning } = useAppToasts();
const timelineSearch = useCallback(
(request: TimelineRequest<typeof language> | null, onNextHandler?: OnNextResponseHandler) => {
@ -233,7 +230,7 @@ export const useTimelineEventsHandler = ({
abortCtrl.current = new AbortController();
setLoading(true);
if (data && data.search) {
const { endTracking } = startTracking();
startTracking();
const abortSignal = abortCtrl.current.signal;
searchSubscription$.current = data.search
.search<TimelineRequest<typeof language>, TimelineResponse<typeof language>>(
@ -270,11 +267,6 @@ export const useTimelineEventsHandler = ({
setFilterStatus(request.filterStatus);
setLoading(false);
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
setLoading(false);
endTracking('invalid');
addWarning(ERROR_TIMELINE_EVENTS);
searchSubscription$.current.unsubscribe();
}
},
@ -292,7 +284,7 @@ export const useTimelineEventsHandler = ({
asyncSearch();
refetch.current = asyncSearch;
},
[skip, data, entityType, dataViewId, addWarning, startTracking, dispatch, id, prevFilterStatus]
[skip, data, entityType, dataViewId, startTracking, dispatch, id, prevFilterStatus]
);
useEffect(() => {

View file

@ -9,7 +9,7 @@ import type { Observable } from 'rxjs';
import { filter } from 'rxjs/operators';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { isErrorResponse, isCompleteResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import type {
CtiEventEnrichmentRequestOptions,
CtiEventEnrichmentStrategyResponse,
@ -46,6 +46,4 @@ export const getEventEnrichment = ({
export const getEventEnrichmentComplete = (
props: GetEventEnrichmentProps
): Observable<CtiEventEnrichmentStrategyResponse> =>
getEventEnrichment(props).pipe(
filter((response) => isErrorResponse(response) || isCompleteResponse(response))
);
getEventEnrichment(props).pipe(filter((response) => isCompleteResponse(response)));

View file

@ -10,7 +10,7 @@ import { noop } from 'lodash/fp';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import type { inputsModel } from '../../../store';
import { useKibana } from '../../../lib/kibana';
import type {
@ -59,7 +59,7 @@ export const useTimelineLastEventTime = ({
refetch: refetch.current,
errorMessage: undefined,
});
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const timelineLastEventTimeSearch = useCallback(
(request: TimelineEventsLastEventTimeRequestOptions) => {
@ -85,9 +85,6 @@ export const useTimelineLastEventTime = ({
lastSeen: response.lastSeen,
refetch: refetch.current,
}));
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.ERROR_LAST_EVENT_TIME);
}
},
error: (msg) => {
@ -107,7 +104,7 @@ export const useTimelineLastEventTime = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, addError, addWarning]
[data.search, addError]
);
useEffect(() => {

View file

@ -7,13 +7,6 @@
import { i18n } from '@kbn/i18n';
export const ERROR_LAST_EVENT_TIME = i18n.translate(
'xpack.securitySolution.lastEventTime.errorSearchDescription',
{
defaultMessage: `An error has occurred on last event time search`,
}
);
export const FAIL_LAST_EVENT_TIME = i18n.translate(
'xpack.securitySolution.lastEventTime.failSearchDescription',
{

View file

@ -190,19 +190,6 @@ describe('useMatrixHistogram', () => {
expect(mockEndTracking).toHaveBeenCalledWith('success');
});
it('should end tracking error when the partial request is invalid', () => {
(useKibana().services.data.search.search as jest.Mock).mockReturnValueOnce({
subscribe: ({ next }: { next: Function }) => next(null),
});
renderHook(useMatrixHistogram, {
initialProps: props,
wrapper: TestProviders,
});
expect(mockEndTracking).toHaveBeenCalledWith('invalid');
});
it('should end tracking error when the request fails', () => {
(useKibana().services.data.search.search as jest.Mock).mockReturnValueOnce({
subscribe: ({ error }: { error: Function }) => error('some error'),

View file

@ -10,7 +10,7 @@ import { getOr, noop } from 'lodash/fp';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Subscription } from 'rxjs';
import { isErrorResponse, isCompleteResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import type { MatrixHistogramQueryProps } from '../../components/matrix_histogram/types';
import type { inputsModel } from '../../store';
import { createFilter } from '../helpers';
@ -92,7 +92,7 @@ export const useMatrixHistogram = ({
...(isPtrIncluded != null ? { isPtrIncluded } : {}),
...(includeMissingData != null ? { includeMissingData } : {}),
});
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const [matrixHistogramResponse, setMatrixHistogramResponse] = useState<UseMatrixHistogramArgs>({
data: [],
@ -138,11 +138,6 @@ export const useMatrixHistogram = ({
}));
endTracking('success');
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.ERROR_MATRIX_HISTOGRAM);
endTracking('invalid');
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {
@ -160,7 +155,7 @@ export const useMatrixHistogram = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, histogramType, addWarning, addError, errorMessage, startTracking]
[data.search, histogramType, addError, errorMessage, startTracking]
);
useEffect(() => {

View file

@ -273,14 +273,18 @@ describe('useSearchStrategy', () => {
expect(mockEndTracking).toBeCalledWith('success');
});
it('should track invalid search result', () => {
mockResponse.mockReturnValueOnce({}); // mock invalid empty response
it('should handle search error', () => {
mockResponse.mockImplementation(() => {
throw new Error(
'simulated search response error, which could be 1) undefined response, 2) response without rawResponse, or 3) partial response'
);
});
const { result } = renderHook(() => useSearch<FactoryQueryTypes>(factoryQueryType));
result.current({ request, abortSignal: new AbortController().signal });
expect(mockStartTracking).toBeCalledTimes(1);
expect(mockEndTracking).toBeCalledWith('invalid');
expect(mockEndTracking).toBeCalledWith('error');
});
it('should track error search result', () => {
@ -310,14 +314,5 @@ describe('useSearchStrategy', () => {
expect(mockEndTracking).toBeCalledTimes(1);
expect(mockEndTracking).toBeCalledWith('aborted');
});
it('should show toast warning when the API returns partial invalid response', () => {
mockResponse.mockReturnValueOnce({}); // mock invalid empty response
const { result } = renderHook(() => useSearch<FactoryQueryTypes>(factoryQueryType));
result.current({ request, abortSignal: new AbortController().signal });
expect(mockAddToastWarning).toBeCalled();
});
});
});

View file

@ -47,7 +47,6 @@ export const useSearch = <QueryType extends FactoryQueryTypes>(
factoryQueryType: QueryType
): UseSearchFunction<QueryType> => {
const { data } = useKibana().services;
const { addWarning } = useAppToasts();
const { startTracking } = useTrackHttpRequest();
const search = useCallback<UseSearchFunction<QueryType>>(
@ -65,16 +64,11 @@ export const useSearch = <QueryType extends FactoryQueryTypes>(
abortSignal,
}
)
.pipe(filter((response) => isErrorResponse(response) || isCompleteResponse(response)));
.pipe(filter((response) => isCompleteResponse(response)));
observable.subscribe({
next: (response) => {
if (isErrorResponse(response)) {
addWarning(i18n.INVALID_RESPONSE_WARNING_SEARCH_STRATEGY(factoryQueryType));
endTracking('invalid');
} else {
endTracking('success');
}
endTracking('success');
},
error: () => {
endTracking(abortSignal.aborted ? 'aborted' : 'error');
@ -83,7 +77,7 @@ export const useSearch = <QueryType extends FactoryQueryTypes>(
return observable;
},
[addWarning, data.search, factoryQueryType, startTracking]
[data.search, factoryQueryType, startTracking]
);
return search;

View file

@ -10,7 +10,7 @@ import { noop } from 'lodash/fp';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import { useAppToasts } from '../../../../../common/hooks/use_app_toasts';
import type { inputsModel } from '../../../../../common/store';
import { createFilter } from '../../../../../common/containers/helpers';
@ -69,7 +69,7 @@ export const useNetworkKpiDns = ({
isInspected: false,
refetch: refetch.current,
});
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const networkKpiDnsSearch = useCallback(
(request: NetworkKpiDnsRequestOptions | null) => {
@ -97,10 +97,6 @@ export const useNetworkKpiDns = ({
refetch: refetch.current,
}));
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.ERROR_NETWORK_KPI_DNS);
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {
@ -117,7 +113,7 @@ export const useNetworkKpiDns = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, addError, addWarning, skip]
[data.search, addError, skip]
);
useEffect(() => {

View file

@ -10,7 +10,7 @@ import { noop } from 'lodash/fp';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import { useAppToasts } from '../../../../../common/hooks/use_app_toasts';
import type { inputsModel } from '../../../../../common/store';
import { createFilter } from '../../../../../common/containers/helpers';
@ -70,7 +70,7 @@ export const useNetworkKpiNetworkEvents = ({
isInspected: false,
refetch: refetch.current,
});
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const networkKpiNetworkEventsSearch = useCallback(
(request: NetworkKpiNetworkEventsRequestOptions | null) => {
@ -101,10 +101,6 @@ export const useNetworkKpiNetworkEvents = ({
refetch: refetch.current,
}));
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.ERROR_NETWORK_KPI_NETWORK_EVENTS);
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {
@ -121,7 +117,7 @@ export const useNetworkKpiNetworkEvents = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, addError, addWarning, skip]
[data.search, addError, skip]
);
useEffect(() => {

View file

@ -10,7 +10,7 @@ import { noop } from 'lodash/fp';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import { useAppToasts } from '../../../../../common/hooks/use_app_toasts';
import type { inputsModel } from '../../../../../common/store';
import { createFilter } from '../../../../../common/containers/helpers';
@ -70,7 +70,7 @@ export const useNetworkKpiTlsHandshakes = ({
isInspected: false,
refetch: refetch.current,
});
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const networkKpiTlsHandshakesSearch = useCallback(
(request: NetworkKpiTlsHandshakesRequestOptions | null) => {
@ -100,10 +100,6 @@ export const useNetworkKpiTlsHandshakes = ({
refetch: refetch.current,
}));
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.ERROR_NETWORK_KPI_TLS_HANDSHAKES);
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {
@ -120,7 +116,7 @@ export const useNetworkKpiTlsHandshakes = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, addError, addWarning, skip]
[data.search, addError, skip]
);
useEffect(() => {

View file

@ -10,7 +10,7 @@ import { noop } from 'lodash/fp';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import { useAppToasts } from '../../../../../common/hooks/use_app_toasts';
import type { inputsModel } from '../../../../../common/store';
import { createFilter } from '../../../../../common/containers/helpers';
@ -70,7 +70,7 @@ export const useNetworkKpiUniqueFlows = ({
isInspected: false,
refetch: refetch.current,
});
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const networkKpiUniqueFlowsSearch = useCallback(
(request: NetworkKpiUniqueFlowsRequestOptions | null) => {
@ -100,10 +100,6 @@ export const useNetworkKpiUniqueFlows = ({
refetch: refetch.current,
}));
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.ERROR_NETWORK_KPI_UNIQUE_FLOWS);
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {
@ -120,7 +116,7 @@ export const useNetworkKpiUniqueFlows = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, addError, addWarning, skip]
[data.search, addError, skip]
);
useEffect(() => {

View file

@ -10,7 +10,7 @@ import { noop } from 'lodash/fp';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import { useAppToasts } from '../../../../../common/hooks/use_app_toasts';
import type { inputsModel } from '../../../../../common/store';
import { createFilter } from '../../../../../common/containers/helpers';
@ -77,7 +77,7 @@ export const useNetworkKpiUniquePrivateIps = ({
isInspected: false,
refetch: refetch.current,
});
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const networkKpiUniquePrivateIpsSearch = useCallback(
(request: NetworkKpiUniquePrivateIpsRequestOptions | null) => {
@ -112,10 +112,6 @@ export const useNetworkKpiUniquePrivateIps = ({
refetch: refetch.current,
}));
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.ERROR_NETWORK_KPI_UNIQUE_PRIVATE_IPS);
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {
@ -132,7 +128,7 @@ export const useNetworkKpiUniquePrivateIps = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, addError, addWarning, skip]
[data.search, addError, skip]
);
useEffect(() => {

View file

@ -9,7 +9,7 @@ import { filter } from 'rxjs/operators';
import { useEffect, useState } from 'react';
import { useObservable, withOptionalSignal } from '@kbn/securitysolution-hook-utils';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/public';
import { isCompleteResponse } from '@kbn/data-plugin/public';
import { useKibana } from '../../../common/lib/kibana';
import type {
Bucket,
@ -51,7 +51,7 @@ export const getTiDataSourcesComplete = (
): Observable<CtiDataSourceStrategyResponse> => {
return getTiDataSources(props).pipe(
filter((response) => {
return isErrorResponse(response) || isCompleteResponse(response);
return isCompleteResponse(response);
})
);
};

View file

@ -11,7 +11,7 @@ import ReactDOM from 'react-dom';
import deepEqual from 'fast-deep-equal';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import { EntityType } from '@kbn/timelines-plugin/common';
import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
import { useKibana } from '../../../common/lib/kibana';
@ -62,7 +62,7 @@ export const useTimelineEventsDetails = ({
const [loading, setLoading] = useState(true);
const [timelineDetailsRequest, setTimelineDetailsRequest] =
useState<TimelineEventsDetailsRequestOptions | null>(null);
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const [timelineDetailsResponse, setTimelineDetailsResponse] =
useState<EventsArgs['detailsData']>(null);
@ -99,10 +99,6 @@ export const useTimelineEventsDetails = ({
searchSubscription$.current.unsubscribe();
});
});
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.FAIL_TIMELINE_DETAILS);
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {
@ -117,7 +113,7 @@ export const useTimelineEventsDetails = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, addError, addWarning, skip]
[data.search, addError, skip]
);
useEffect(() => {

View file

@ -12,7 +12,7 @@ import { useDispatch } from 'react-redux';
import { Subscription } from 'rxjs';
import type { DataView } from '@kbn/data-plugin/common';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import type { ESQuery } from '../../../common/typed_json';
import type { inputsModel } from '../../common/store';
@ -32,7 +32,6 @@ import type {
} from '../../../common/search_strategy';
import { Direction, TimelineEventsQueries } from '../../../common/search_strategy';
import type { InspectResponse } from '../../types';
import * as i18n from './translations';
import type { KueryFilterQueryKind } from '../../../common/types/timeline';
import { TimelineId } from '../../../common/types/timeline';
import { useRouteSpy } from '../../common/utils/route/use_route_spy';
@ -42,7 +41,6 @@ import type {
TimelineEqlRequestOptions,
TimelineEqlResponse,
} from '../../../common/search_strategy/timeline/events/eql';
import { useAppToasts } from '../../common/hooks/use_app_toasts';
import { useTrackHttpRequest } from '../../common/lib/apm/use_track_http_request';
import { APP_UI_ID } from '../../../common/constants';
@ -221,8 +219,6 @@ export const useTimelineEventsHandler = ({
}
}, [setUpdated, timelineResponse.updatedAt]);
const { addWarning } = useAppToasts();
const timelineSearch = useCallback(
async (
request: TimelineRequest<typeof language> | null,
@ -275,11 +271,6 @@ export const useTimelineEventsHandler = ({
return newTimelineResponse;
});
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
endTracking('invalid');
setLoading(false);
addWarning(i18n.ERROR_TIMELINE_EVENTS);
searchSubscription$.current.unsubscribe();
}
},
@ -335,17 +326,7 @@ export const useTimelineEventsHandler = ({
await asyncSearch();
refetch.current = asyncSearch;
},
[
pageName,
skip,
id,
startTracking,
data.search,
dataViewId,
addWarning,
refetchGrid,
wrappedLoadPage,
]
[pageName, skip, id, startTracking, data.search, dataViewId, refetchGrid, wrappedLoadPage]
);
useEffect(() => {

View file

@ -10,7 +10,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
import deepEqual from 'fast-deep-equal';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/public';
import { isCompleteResponse } from '@kbn/data-plugin/public';
import type { inputsModel } from '../../../common/store';
import { useKibana } from '../../../common/lib/kibana';
import type {
@ -46,7 +46,7 @@ export const useTimelineKpis = ({
);
const [timelineKpiResponse, setTimelineKpiResponse] =
useState<TimelineKpiStrategyResponse | null>(null);
const { addError, addWarning } = useAppToasts();
const { addError } = useAppToasts();
const timelineKpiSearch = useCallback(
(request: TimelineKpiStrategyRequest | null) => {
@ -68,10 +68,6 @@ export const useTimelineKpis = ({
setLoading(false);
setTimelineKpiResponse(response);
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
setLoading(false);
addWarning(i18n.FAIL_TIMELINE_KPI_DETAILS);
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {
@ -86,7 +82,7 @@ export const useTimelineKpis = ({
asyncSearch();
refetch.current = asyncSearch;
},
[data.search, addError, addWarning]
[data.search, addError]
);
useEffect(() => {

View file

@ -9,7 +9,6 @@ import {
IEsSearchRequest,
IKibanaSearchResponse,
isCompleteResponse,
isErrorResponse,
} from '@kbn/data-plugin/common';
import { ISearchStart } from '@kbn/data-plugin/public';
import { RequestAdapter } from '@kbn/inspector-plugin/common';
@ -97,9 +96,6 @@ export const search = async <TResponse, T = {}>(
if (isCompleteResponse(response)) {
inspect.recordRequestCompletion(searchRequest, response);
resolve(response.rawResponse);
} else if (isErrorResponse(response)) {
inspect.recordRequestError(response);
reject(response);
}
},
error: (requestError) => {

View file

@ -33569,7 +33569,6 @@
"xpack.securitySolution.kubernetes.columnPod": "Pod",
"xpack.securitySolution.kubernetes.columnSessionStart": "Date de démarrage",
"xpack.securitySolution.landing.threatHunting.hostsDescription": "Aperçu complet de tous les hôtes et événements de sécurité des hôtes.",
"xpack.securitySolution.lastEventTime.errorSearchDescription": "Une erreur s'est produite sur la recherche de dernière heure de l'événement",
"xpack.securitySolution.lastEventTime.failSearchDescription": "Impossible de lancer une recherche sur la dernière heure de l'événement",
"xpack.securitySolution.lensEmbeddable.NoDataToDisplay.title": "Aucune donnée à afficher",
"xpack.securitySolution.licensing.unsupportedMachineLearningMessage": "Votre licence ne prend pas en charge le Machine Learning. Veuillez mettre votre licence à niveau.",

View file

@ -33568,7 +33568,6 @@
"xpack.securitySolution.kubernetes.columnPod": "ポッド",
"xpack.securitySolution.kubernetes.columnSessionStart": "開始日",
"xpack.securitySolution.landing.threatHunting.hostsDescription": "すべてのホストとホスト関連のセキュリティイベントに関する包括的な概要。",
"xpack.securitySolution.lastEventTime.errorSearchDescription": "前回のイベント時刻検索でエラーが発生しました。",
"xpack.securitySolution.lastEventTime.failSearchDescription": "前回のイベント時刻で検索を実行できませんでした",
"xpack.securitySolution.lensEmbeddable.NoDataToDisplay.title": "表示するデータがありません",
"xpack.securitySolution.licensing.unsupportedMachineLearningMessage": "ご使用のライセンスは機械翻訳をサポートしていません。ライセンスをアップグレードしてください。",

View file

@ -33564,7 +33564,6 @@
"xpack.securitySolution.kubernetes.columnPod": "Pod",
"xpack.securitySolution.kubernetes.columnSessionStart": "开始日期",
"xpack.securitySolution.landing.threatHunting.hostsDescription": "所有主机和主机相关安全事件的全面概览。",
"xpack.securitySolution.lastEventTime.errorSearchDescription": "搜索上次事件时间时发生错误",
"xpack.securitySolution.lastEventTime.failSearchDescription": "无法对上次事件时间执行搜索",
"xpack.securitySolution.lensEmbeddable.NoDataToDisplay.title": "没有可显示的数据",
"xpack.securitySolution.licensing.unsupportedMachineLearningMessage": "您的许可证不支持 Machine Learning。请升级您的许可证。",

View file

@ -6,7 +6,7 @@
*/
import sinon from 'sinon';
import { of } from 'rxjs';
import { of, throwError } from 'rxjs';
import { act, renderHook } from '@testing-library/react-hooks';
import { useFetchAlerts, FetchAlertsArgs, FetchAlertResp } from './use_fetch_alerts';
import { useKibana } from '../../../../common/lib/kibana';
@ -286,9 +286,10 @@ describe('useFetchAlerts', () => {
]);
});
it('returns the correct response if the request is undefined', () => {
// @ts-expect-error
const obs$ = of<IKibanaSearchResponse>(undefined);
it('handles search error', () => {
const obs$ = throwError(
'simulated search response error, which could be 1) undefined response, 2) response without rawResponse, or 3) partial response'
);
dataSearchMock.mockReturnValue(obs$);
const { result } = renderHook(() => useFetchAlerts(args));
@ -308,7 +309,7 @@ describe('useFetchAlerts', () => {
expect(showErrorMock).toHaveBeenCalled();
});
it('returns the correct response if the request is running', () => {
it('returns the correct response if the search response is running', () => {
const obs$ = of<IKibanaSearchResponse>({ ...searchResponse, isRunning: true });
dataSearchMock.mockReturnValue(obs$);
const { result } = renderHook(() => useFetchAlerts(args));
@ -327,47 +328,6 @@ describe('useFetchAlerts', () => {
]);
});
it('returns the correct response if the request is partial', () => {
const obs$ = of<IKibanaSearchResponse>({ ...searchResponse, isPartial: true });
dataSearchMock.mockReturnValue(obs$);
const { result } = renderHook(() => useFetchAlerts(args));
expect(result.current).toEqual([
false,
{
...expectedResponse,
alerts: [],
getInspectQuery: expect.anything(),
refetch: expect.anything(),
isInitializing: true,
totalAlerts: -1,
updatedAt: 0,
},
]);
expect(showErrorMock).toHaveBeenCalled();
});
it('returns the correct response if there is no rawResponse', () => {
// @ts-expect-error
const obs$ = of<IKibanaSearchResponse>({ id: '1', isRunning: true, isPartial: false });
dataSearchMock.mockReturnValue(obs$);
const { result } = renderHook(() => useFetchAlerts(args));
expect(result.current).toEqual([
false,
{
...expectedResponse,
alerts: [],
getInspectQuery: expect.anything(),
refetch: expect.anything(),
isInitializing: true,
totalAlerts: -1,
updatedAt: 0,
},
]);
expect(showErrorMock).toHaveBeenCalled();
});
it('returns the correct total alerts if the total alerts in the response is an object', () => {
const obs$ = of<IKibanaSearchResponse>({
...searchResponse,

View file

@ -12,7 +12,7 @@ import { noop } from 'lodash';
import { useCallback, useEffect, useReducer, useRef, useMemo } from 'react';
import { Subscription } from 'rxjs';
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
import { isCompleteResponse } from '@kbn/data-plugin/common';
import type {
RuleRegistrySearchRequest,
RuleRegistrySearchRequestPagination,
@ -27,7 +27,6 @@ import type {
import type { Alert, Alerts, GetInspectQuery, InspectQuery } from '../../../../types';
import { useKibana } from '../../../../common/lib/kibana';
import { DefaultSort } from './constants';
import * as i18n from './translations';
export interface FetchAlertsArgs {
featureIds: ValidFeatureId[];
@ -260,10 +259,6 @@ const useFetchAlerts = ({
totalAlerts,
});
searchSubscription$.current.unsubscribe();
} else if (isErrorResponse(response)) {
dispatch({ type: 'loading', loading: false });
data.search.showError(new Error(i18n.ERROR_FETCH_ALERTS));
searchSubscription$.current.unsubscribe();
}
},
error: (msg) => {