diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx
index 0d60bd588f71..4a79f30a17a0 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx
@@ -324,8 +324,11 @@ describe('IndexPattern Data Panel', () => {
};
}
- async function testExistenceLoading(stateChanges?: unknown, propChanges?: unknown) {
- const props = testProps();
+ async function testExistenceLoading(
+ stateChanges?: unknown,
+ propChanges?: unknown,
+ props = testProps()
+ ) {
const inst = mountWithIntl();
await act(async () => {
@@ -536,6 +539,25 @@ describe('IndexPattern Data Panel', () => {
expect(core.http.post).toHaveBeenCalledTimes(2);
expect(overlapCount).toEqual(0);
});
+
+ it("should default to empty dsl if query can't be parsed", async () => {
+ const props = {
+ ...testProps(),
+ query: {
+ language: 'kuery',
+ query: '@timestamp : NOT *',
+ },
+ };
+ await testExistenceLoading(undefined, undefined, props);
+
+ expect((props.core.http.post as jest.Mock).mock.calls[0][1].body).toContain(
+ JSON.stringify({
+ must_not: {
+ match_all: {},
+ },
+ })
+ );
+ });
});
describe('displaying field list', () => {
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx
index eb7940634d78..91c068c2b4fa 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx
@@ -22,7 +22,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
-import { DataPublicPluginStart } from 'src/plugins/data/public';
+import { DataPublicPluginStart, EsQueryConfig, Query, Filter } from 'src/plugins/data/public';
import { DatasourceDataPanelProps, DataType, StateSetter } from '../types';
import { ChildDragDropProvider, DragContextState } from '../drag_drop';
import { FieldItem } from './field_item';
@@ -74,6 +74,27 @@ const fieldTypeNames: Record = {
ip: i18n.translate('xpack.lens.datatypes.ipAddress', { defaultMessage: 'IP' }),
};
+// Wrapper around esQuery.buildEsQuery, handling errors (e.g. because a query can't be parsed) by
+// returning a query dsl object not matching anything
+function buildSafeEsQuery(
+ indexPattern: IIndexPattern,
+ query: Query,
+ filters: Filter[],
+ queryConfig: EsQueryConfig
+) {
+ try {
+ return esQuery.buildEsQuery(indexPattern, query, filters, queryConfig);
+ } catch (e) {
+ return {
+ bool: {
+ must_not: {
+ match_all: {},
+ },
+ },
+ };
+ }
+}
+
export function IndexPatternDataPanel({
setState,
state,
@@ -106,7 +127,7 @@ export function IndexPatternDataPanel({
timeFieldName: indexPatterns[id].timeFieldName,
}));
- const dslQuery = esQuery.buildEsQuery(
+ const dslQuery = buildSafeEsQuery(
indexPatterns[currentIndexPatternId] as IIndexPattern,
query,
filters,
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx
index 815725f4331a..fabf9e9e9bff 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx
@@ -198,10 +198,12 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) {
className={`lnsFieldItem__info ${infoIsOpen ? 'lnsFieldItem__info-isOpen' : ''}`}
data-test-subj={`lnsFieldListPanelField-${field.name}`}
onClick={() => {
- togglePopover();
+ if (exists) {
+ togglePopover();
+ }
}}
onKeyPress={(event) => {
- if (event.key === 'ENTER') {
+ if (exists && event.key === 'ENTER') {
togglePopover();
}
}}