From 781ac42577f340a5cf90c326f86c5b6f8afe9000 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 14 May 2018 15:09:22 -0600 Subject: [PATCH] [input controls] safely handle case where control index pattern no longer exists (#18931) (#19050) * handle case where control index pattern no longer exists * fix errors when vis is edited with missing index pattern --- .../public/components/editor/field_select.js | 8 +++++++- .../components/editor/index_pattern_select.js | 10 ++++++---- .../public/components/vis/list_control.js | 6 +++++- .../input_control_vis/public/control/control.js | 5 +++++ .../public/control/list_control_factory.js | 17 ++++++++++++++--- .../public/control/range_control_factory.js | 15 +++++++++++++-- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/core_plugins/input_control_vis/public/components/editor/field_select.js b/src/core_plugins/input_control_vis/public/components/editor/field_select.js index 5a0813ccdc56..817e5ce94017 100644 --- a/src/core_plugins/input_control_vis/public/components/editor/field_select.js +++ b/src/core_plugins/input_control_vis/public/components/editor/field_select.js @@ -48,7 +48,13 @@ export class FieldSelect extends Component { return; } - const indexPattern = await this.props.getIndexPattern(indexPatternId); + let indexPattern; + try { + indexPattern = await this.props.getIndexPattern(indexPatternId); + } catch (err) { + // index pattern no longer exists + return; + } if (this._hasUnmounted) { return; diff --git a/src/core_plugins/input_control_vis/public/components/editor/index_pattern_select.js b/src/core_plugins/input_control_vis/public/components/editor/index_pattern_select.js index c56518b3b758..f7a1d74e29f1 100644 --- a/src/core_plugins/input_control_vis/public/components/editor/index_pattern_select.js +++ b/src/core_plugins/input_control_vis/public/components/editor/index_pattern_select.js @@ -46,13 +46,15 @@ export class IndexPatternSelect extends Component { return; } - const indexPattern = await this.props.getIndexPattern(indexPatternId); - - if (!this._isMounted) { + let indexPattern; + try { + indexPattern = await this.props.getIndexPattern(indexPatternId); + } catch (err) { + // index pattern no longer exists return; } - if (!indexPattern) { + if (!this._isMounted) { return; } diff --git a/src/core_plugins/input_control_vis/public/components/vis/list_control.js b/src/core_plugins/input_control_vis/public/components/vis/list_control.js index 8caa4c60bf83..8db1f671f383 100644 --- a/src/core_plugins/input_control_vis/public/components/vis/list_control.js +++ b/src/core_plugins/input_control_vis/public/components/vis/list_control.js @@ -66,9 +66,13 @@ ListControl.propTypes = { id: PropTypes.string.isRequired, label: PropTypes.string.isRequired, selectedOptions: PropTypes.arrayOf(comboBoxOptionShape).isRequired, - options: PropTypes.arrayOf(comboBoxOptionShape).isRequired, + options: PropTypes.arrayOf(comboBoxOptionShape), disableMsg: PropTypes.string, multiselect: PropTypes.bool.isRequired, controlIndex: PropTypes.number.isRequired, stageFilter: PropTypes.func.isRequired }; + +ListControl.defaultProps = { + options: [], +}; diff --git a/src/core_plugins/input_control_vis/public/control/control.js b/src/core_plugins/input_control_vis/public/control/control.js index 9bc5cf5162be..25773904a621 100644 --- a/src/core_plugins/input_control_vis/public/control/control.js +++ b/src/core_plugins/input_control_vis/public/control/control.js @@ -6,9 +6,14 @@ which doesn't exist on any documents in the "${indexPatternName}" index pattern. Choose a different field or index documents that contain values for this field.`; } +export function noIndexPatternMsg(indexPatternId) { + return `Could not locate index-pattern id: ${indexPatternId}.`; +} + export class Control { constructor(controlParams, filterManager, kbnApi, useTimeFilter) { this.id = controlParams.id; + this.controlParams = controlParams; this.options = controlParams.options; this.type = controlParams.type; this.label = controlParams.label ? controlParams.label : controlParams.fieldName; diff --git a/src/core_plugins/input_control_vis/public/control/list_control_factory.js b/src/core_plugins/input_control_vis/public/control/list_control_factory.js index a1c062664137..e58c00f163da 100644 --- a/src/core_plugins/input_control_vis/public/control/list_control_factory.js +++ b/src/core_plugins/input_control_vis/public/control/list_control_factory.js @@ -1,7 +1,8 @@ import _ from 'lodash'; import { Control, - noValuesDisableMsg + noValuesDisableMsg, + noIndexPatternMsg, } from './control'; import { PhraseFilterManager } from './filter_manager/phrase_filter_manager'; import { createSearchSource } from './create_search_source'; @@ -35,6 +36,12 @@ const termsAgg = (field, size, direction) => { class ListControl extends Control { async fetch() { + const indexPattern = this.filterManager.getIndexPattern(); + if (!indexPattern) { + this.disable(noIndexPatternMsg(this.controlParams.indexPattern)); + return; + } + let ancestorFilters; if (this.hasAncestors()) { if (this.hasUnsetAncestor()) { @@ -52,7 +59,6 @@ class ListControl extends Control { ancestorFilters = this.getAncestorFilters(); } - const indexPattern = this.filterManager.getIndexPattern(); const fieldName = this.filterManager.fieldName; const initialSearchSourceState = { timeout: '1s', @@ -89,7 +95,12 @@ class ListControl extends Control { } export async function listControlFactory(controlParams, kbnApi, useTimeFilter) { - const indexPattern = await kbnApi.indexPatterns.get(controlParams.indexPattern); + let indexPattern; + try { + indexPattern = await kbnApi.indexPatterns.get(controlParams.indexPattern); + } catch (err) { + // ignore not found error and return control so it can be displayed in disabled state. + } return new ListControl( controlParams, diff --git a/src/core_plugins/input_control_vis/public/control/range_control_factory.js b/src/core_plugins/input_control_vis/public/control/range_control_factory.js index b66d2b70b007..f4f0f8dc013f 100644 --- a/src/core_plugins/input_control_vis/public/control/range_control_factory.js +++ b/src/core_plugins/input_control_vis/public/control/range_control_factory.js @@ -1,7 +1,8 @@ import _ from 'lodash'; import { Control, - noValuesDisableMsg + noValuesDisableMsg, + noIndexPatternMsg, } from './control'; import { RangeFilterManager } from './filter_manager/range_filter_manager'; import { createSearchSource } from './create_search_source'; @@ -30,6 +31,11 @@ class RangeControl extends Control { async fetch() { const indexPattern = this.filterManager.getIndexPattern(); + if (!indexPattern) { + this.disable(noIndexPatternMsg(this.controlParams.indexPattern)); + return; + } + const fieldName = this.filterManager.fieldName; const aggs = minMaxAgg(indexPattern.fields.byName[fieldName]); @@ -60,7 +66,12 @@ class RangeControl extends Control { } export async function rangeControlFactory(controlParams, kbnApi, useTimeFilter) { - const indexPattern = await kbnApi.indexPatterns.get(controlParams.indexPattern); + let indexPattern; + try { + indexPattern = await kbnApi.indexPatterns.get(controlParams.indexPattern); + } catch (err) { + // ignore not found error and return control so it can be displayed in disabled state. + } const unsetValue = { min: 0, max: 1 }; return new RangeControl( controlParams,