From 56ba6602ab7c4b3289f6fb4ba9ffb18a89c0b21e Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Mon, 16 Sep 2019 20:10:00 +0300 Subject: [PATCH] =?UTF-8?q?Moved=20KbnError=20base=20class=20=E2=87=92=20k?= =?UTF-8?q?ibana=5Futils=20(#45532)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * moved errors base class to kibana_utils * Fixed tests for ui/errors imports * fixed test path * Restored Request Failure resp field * Restored savedObjectType and savedObjectId * simplified Error class extension * updated constructors --- .../lib/map_geo_bounding_box.js | 2 +- .../filter_manager/lib/map_geo_polygon.js | 2 +- .../filter/filter_manager/lib/map_phrase.js | 2 +- .../filter/filter_manager/lib/map_range.js | 2 +- .../data/public/index_patterns/errors.ts | 12 +- .../index_patterns/index_pattern.test.ts | 3 +- .../index_patterns/index_pattern.tsx | 3 +- .../kibana/public/dashboard/index.js | 2 +- .../__jest__/objects_table.test.js | 13 - .../components/flyout/__jest__/flyout.test.js | 13 - .../__jest__/relationships.test.js | 13 - .../components/table/__jest__/table.test.js | 13 - .../__jest__/resolve_saved_objects.test.js | 10 +- .../objects/lib/resolve_saved_objects.js | 2 +- .../ui/public/agg_types/param_types/field.ts | 3 +- .../courier/fetch/call_response_handlers.js | 2 +- src/legacy/ui/public/courier/fetch/errors.ts | 34 +++ src/legacy/ui/public/errors.js | 249 ------------------ .../__tests__/persisted_state_provider.js | 2 +- .../ui/public/persisted_state/errors.ts | 26 ++ .../public/persisted_state/persisted_state.js | 3 +- .../saved_objects/__tests__/saved_object.js | 2 +- .../ui/public/saved_objects/saved_object.js | 3 +- .../ui/public/url/redirect_when_missing.js | 2 +- src/legacy/ui/public/vislib/errors.ts | 56 ++++ .../ui/public/vislib/lib/_error_handler.js | 2 +- src/legacy/ui/public/vislib/lib/axis/axis.js | 2 +- .../ui/public/vislib/lib/axis/axis_scale.js | 3 +- src/legacy/ui/public/vislib/lib/handler.js | 2 +- src/legacy/ui/public/vislib/vis.js | 4 +- .../public/vislib/visualizations/pie_chart.js | 2 +- .../public/errors/errors.test.ts} | 45 +--- .../kibana_utils/public/errors/errors.ts | 70 +++++ .../kibana_utils/public/errors/index.ts | 20 ++ src/plugins/kibana_utils/public/index.ts | 1 + .../legacy/plugins/ml/public/util/ml_error.js | 2 +- 36 files changed, 245 insertions(+), 382 deletions(-) create mode 100644 src/legacy/ui/public/courier/fetch/errors.ts delete mode 100644 src/legacy/ui/public/errors.js create mode 100644 src/legacy/ui/public/persisted_state/errors.ts create mode 100644 src/legacy/ui/public/vislib/errors.ts rename src/{legacy/ui/public/__tests__/errors.js => plugins/kibana_utils/public/errors/errors.test.ts} (52%) create mode 100644 src/plugins/kibana_utils/public/errors/errors.ts create mode 100644 src/plugins/kibana_utils/public/errors/index.ts diff --git a/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_geo_bounding_box.js b/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_geo_bounding_box.js index cba1344a53efb..bfb4bdd4ca3b4 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_geo_bounding_box.js +++ b/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_geo_bounding_box.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import { SavedObjectNotFound } from 'ui/errors'; +import { SavedObjectNotFound } from '../../../../../../../plugins/kibana_utils/public'; function getParams(filter, indexPattern) { const type = 'geo_bounding_box'; diff --git a/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_geo_polygon.js b/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_geo_polygon.js index 913ca1d30a53f..cbe38eb141917 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_geo_polygon.js +++ b/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_geo_polygon.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import { SavedObjectNotFound } from 'ui/errors'; +import { SavedObjectNotFound } from '../../../../../../../plugins/kibana_utils/public'; function getParams(filter, indexPattern) { const type = 'geo_polygon'; diff --git a/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_phrase.js b/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_phrase.js index b7ee58e9078ba..a87c315d982a2 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_phrase.js +++ b/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_phrase.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import { SavedObjectNotFound } from 'ui/errors'; +import { SavedObjectNotFound } from '../../../../../../../plugins/kibana_utils/public'; function isScriptedPhrase(filter) { const value = _.get(filter, ['script', 'script', 'params', 'value']); diff --git a/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_range.js b/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_range.js index dabc6a4f9bd19..3c76998989580 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_range.js +++ b/src/legacy/core_plugins/data/public/filter/filter_manager/lib/map_range.js @@ -18,7 +18,7 @@ */ import { has, get } from 'lodash'; -import { SavedObjectNotFound } from 'ui/errors'; +import { SavedObjectNotFound } from '../../../../../../../plugins/kibana_utils/public'; function isScriptedRange(filter) { diff --git a/src/legacy/core_plugins/data/public/index_patterns/errors.ts b/src/legacy/core_plugins/data/public/index_patterns/errors.ts index df7f26ad6673d..c64da47b8c785 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/errors.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/errors.ts @@ -19,8 +19,7 @@ /* eslint-disable */ -// @ts-ignore -import { KbnError } from 'ui/errors'; +import { KbnError } from '../../../../../plugins/kibana_utils/public'; /** * when a mapping already exists for a field the user is attempting to add @@ -28,7 +27,7 @@ import { KbnError } from 'ui/errors'; */ export class IndexPatternAlreadyExists extends KbnError { constructor(name: string) { - super(`An index pattern of "${name}" already exists`, IndexPatternAlreadyExists); + super(`An index pattern of "${name}" already exists`); } } @@ -40,8 +39,7 @@ export class IndexPatternMissingIndices extends KbnError { const defaultMessage = "IndexPattern's configured pattern does not match any indices"; super( - message && message.length ? `No matching indices found: ${message}` : defaultMessage, - IndexPatternMissingIndices + message && message.length ? `No matching indices found: ${message}` : defaultMessage ); } } @@ -51,7 +49,7 @@ export class IndexPatternMissingIndices extends KbnError { */ export class NoDefinedIndexPatterns extends KbnError { constructor() { - super('Define at least one index pattern to continue', NoDefinedIndexPatterns); + super('Define at least one index pattern to continue'); } } @@ -60,6 +58,6 @@ export class NoDefinedIndexPatterns extends KbnError { */ export class NoDefaultIndexPattern extends KbnError { constructor() { - super('Please specify a default index pattern', NoDefaultIndexPattern); + super('Please specify a default index pattern'); } } diff --git a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts index 4a401e0b5e44f..d87f9ed1a87f9 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts @@ -21,8 +21,7 @@ import { defaults, pluck, last, get } from 'lodash'; import { IndexedArray } from 'ui/indexed_array'; import { IndexPattern } from './index_pattern'; -// @ts-ignore -import { DuplicateField } from 'ui/errors'; +import { DuplicateField } from '../../../../../../plugins/kibana_utils/public'; // @ts-ignore import mockLogStashFields from '../../../../../../fixtures/logstash_fields'; // @ts-ignore diff --git a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.tsx b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.tsx index ec1005bdce261..937032ab6c039 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.tsx +++ b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.tsx @@ -24,14 +24,13 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React from 'react'; import chrome from 'ui/chrome'; // @ts-ignore -import { SavedObjectNotFound, DuplicateField } from 'ui/errors'; -// @ts-ignore import { fieldFormats } from 'ui/registry/field_formats'; // @ts-ignore import { expandShorthand } from 'ui/utils/mapping_setup'; import { toastNotifications } from 'ui/notify'; import { findObjectByTitle } from 'ui/saved_objects'; import { SavedObjectsClientContract } from 'src/core/public'; +import { SavedObjectNotFound, DuplicateField } from '../../../../../../plugins/kibana_utils/public'; import { IndexPatternMissingIndices } from '../errors'; import { Field, FieldList, FieldType } from '../fields'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/index.js b/src/legacy/core_plugins/kibana/public/dashboard/index.js index 1c57febb2d4b7..e22eb8e8db91d 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/index.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/index.js @@ -30,7 +30,7 @@ import dashboardTemplate from './dashboard_app.html'; import dashboardListingTemplate from './listing/dashboard_listing_ng_wrapper.html'; import { DashboardConstants, createDashboardEditUrl } from './dashboard_constants'; -import { InvalidJSONProperty, SavedObjectNotFound } from 'ui/errors'; +import { InvalidJSONProperty, SavedObjectNotFound } from '../../../../../plugins/kibana_utils/public'; import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/registry/feature_catalogue'; import { SavedObjectsClientProvider } from 'ui/saved_objects'; import { recentlyAccessed } from 'ui/persisted_log'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/__jest__/objects_table.test.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/__jest__/objects_table.test.js index 51f33f7568369..f7b7f06c2f502 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/__jest__/objects_table.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/__jest__/objects_table.test.js @@ -35,19 +35,6 @@ jest.mock('../components/header', () => ({ Header: () => 'Header', })); -jest.mock('ui/errors', () => ({ - SavedObjectNotFound: class SavedObjectNotFound extends Error { - constructor(options) { - super(); - for (const option in options) { - if (options.hasOwnProperty(option)) { - this[option] = options[option]; - } - } - } - }, -})); - jest.mock('ui/chrome', () => ({ addBasePath: () => '', getInjected: () => ['index-pattern', 'visualization', 'dashboard', 'search'], diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/flyout.test.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/flyout.test.js index c006594605d56..2e80dcd753bc2 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/flyout.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/flyout.test.js @@ -24,19 +24,6 @@ import { Flyout } from '../flyout'; jest.mock('ui/kfetch', () => ({ kfetch: jest.fn() })); -jest.mock('ui/errors', () => ({ - SavedObjectNotFound: class SavedObjectNotFound extends Error { - constructor(options) { - super(); - for (const option in options) { - if (options.hasOwnProperty(option)) { - this[option] = options[option]; - } - } - } - }, -})); - jest.mock('../../../../../lib/import_file', () => ({ importFile: jest.fn(), })); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/relationships.test.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/relationships.test.js index 9ad6190bc30d5..d0c45f8a7ee08 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/relationships.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/relationships.test.js @@ -22,19 +22,6 @@ import { shallowWithIntl } from 'test_utils/enzyme_helpers'; jest.mock('ui/kfetch', () => ({ kfetch: jest.fn() })); -jest.mock('ui/errors', () => ({ - SavedObjectNotFound: class SavedObjectNotFound extends Error { - constructor(options) { - super(); - for (const option in options) { - if (options.hasOwnProperty(option)) { - this[option] = options[option]; - } - } - } - }, -})); - jest.mock('ui/chrome', () => ({ addBasePath: () => '' })); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/table.test.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/table.test.js index 5a8e6bd71049e..e36c340751dc6 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/table.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/table.test.js @@ -24,19 +24,6 @@ import { keyCodes } from '@elastic/eui/lib/services'; jest.mock('ui/kfetch', () => ({ kfetch: jest.fn() })); -jest.mock('ui/errors', () => ({ - SavedObjectNotFound: class SavedObjectNotFound extends Error { - constructor(options) { - super(); - for (const option in options) { - if (options.hasOwnProperty(option)) { - this[option] = options[option]; - } - } - } - }, -})); - jest.mock('ui/chrome', () => ({ addBasePath: () => '' })); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/resolve_saved_objects.test.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/resolve_saved_objects.test.js index e8d8a2469e2ed..eba62cfee4093 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/resolve_saved_objects.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/resolve_saved_objects.test.js @@ -24,7 +24,8 @@ import { saveObject, } from '../resolve_saved_objects'; -jest.mock('ui/errors', () => ({ + +jest.mock('../../../../../../../../../plugins/kibana_utils/public', () => ({ SavedObjectNotFound: class SavedObjectNotFound extends Error { constructor(options) { super(); @@ -36,6 +37,7 @@ jest.mock('ui/errors', () => ({ } }, })); +import { SavedObjectNotFound } from '../../../../../../../../../plugins/kibana_utils/public'; describe('resolveSavedObjects', () => { describe('resolveSavedObjects', () => { @@ -81,7 +83,6 @@ describe('resolveSavedObjects', () => { return { applyESResp: async () => {}, save: async () => { - const { SavedObjectNotFound } = require('ui/errors'); throw new SavedObjectNotFound({ savedObjectType: 'index-pattern', }); @@ -95,7 +96,6 @@ describe('resolveSavedObjects', () => { return { applyESResp: async () => {}, save: async () => { - const { SavedObjectNotFound } = require('ui/errors'); throw new SavedObjectNotFound({ savedObjectType: 'index-pattern', }); @@ -109,7 +109,6 @@ describe('resolveSavedObjects', () => { return { applyESResp: async () => {}, save: async () => { - const { SavedObjectNotFound } = require('ui/errors'); throw new SavedObjectNotFound({ savedObjectType: 'index-pattern', }); @@ -175,7 +174,6 @@ describe('resolveSavedObjects', () => { return { applyESResp: async () => {}, save: async () => { - const { SavedObjectNotFound } = require('ui/errors'); throw new SavedObjectNotFound({ savedObjectType: 'search', }); @@ -189,7 +187,6 @@ describe('resolveSavedObjects', () => { return { applyESResp: async () => {}, save: async () => { - const { SavedObjectNotFound } = require('ui/errors'); throw new SavedObjectNotFound({ savedObjectType: 'index-pattern', }); @@ -204,7 +201,6 @@ describe('resolveSavedObjects', () => { savedSearchId: '1', applyESResp: async () => {}, save: async () => { - const { SavedObjectNotFound } = require('ui/errors'); throw new SavedObjectNotFound({ savedObjectType: 'index-pattern', }); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/resolve_saved_objects.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/resolve_saved_objects.js index eeb5fb778b707..38c936137fc66 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/resolve_saved_objects.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/resolve_saved_objects.js @@ -17,7 +17,7 @@ * under the License. */ -import { SavedObjectNotFound } from 'ui/errors'; +import { SavedObjectNotFound } from '../../../../../../../../plugins/kibana_utils/public'; import { i18n } from '@kbn/i18n'; async function getSavedObject(doc, services) { diff --git a/src/legacy/ui/public/agg_types/param_types/field.ts b/src/legacy/ui/public/agg_types/param_types/field.ts index 83eae1aa55fc2..5fb653e9a65f0 100644 --- a/src/legacy/ui/public/agg_types/param_types/field.ts +++ b/src/legacy/ui/public/agg_types/param_types/field.ts @@ -20,8 +20,7 @@ // @ts-ignore import { i18n } from '@kbn/i18n'; import { AggConfig } from '../../vis'; -// @ts-ignore -import { SavedObjectNotFound } from '../../errors'; +import { SavedObjectNotFound } from '../../../../../plugins/kibana_utils/public'; import { FieldParamEditor } from '../../vis/editors/default/controls/field'; import { BaseParamType } from './base'; import { toastNotifications } from '../../notify'; diff --git a/src/legacy/ui/public/courier/fetch/call_response_handlers.js b/src/legacy/ui/public/courier/fetch/call_response_handlers.js index 379ea68a99b51..aaf82168e385f 100644 --- a/src/legacy/ui/public/courier/fetch/call_response_handlers.js +++ b/src/legacy/ui/public/courier/fetch/call_response_handlers.js @@ -20,7 +20,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiSpacer } from '@elastic/eui'; import { toastNotifications } from '../../notify'; -import { RequestFailure } from '../../errors'; +import { RequestFailure } from './errors'; import { RequestStatus } from './req_status'; import { SearchError } from '../search_strategy/search_error'; import { ShardFailureOpenModalButton } from './components/shard_failure_open_modal_button'; diff --git a/src/legacy/ui/public/courier/fetch/errors.ts b/src/legacy/ui/public/courier/fetch/errors.ts new file mode 100644 index 0000000000000..aba554a795258 --- /dev/null +++ b/src/legacy/ui/public/courier/fetch/errors.ts @@ -0,0 +1,34 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { KbnError } from '../../../../../plugins/kibana_utils/public'; +/** + * Request Failure - When an entire multi request fails + * @param {Error} err - the Error that came back + * @param {Object} resp - optional HTTP response + */ +export class RequestFailure extends KbnError { + public resp: any; + constructor(err: any, resp?: any) { + err = err || false; + super(`Request to Elasticsearch failed: ${JSON.stringify(resp || err.message)}`); + + this.resp = resp; + } +} diff --git a/src/legacy/ui/public/errors.js b/src/legacy/ui/public/errors.js deleted file mode 100644 index b3fb08a78b61d..0000000000000 --- a/src/legacy/ui/public/errors.js +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import angular from 'angular'; -import { createLegacyClass } from './utils/legacy_class'; - -const canStack = (function () { - const err = new Error(); - return !!err.stack; -}()); - -// abstract error class -export class KbnError { - constructor(msg, constructor) { - this.message = msg; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, constructor || KbnError); - } else if (canStack) { - this.stack = (new Error()).stack; - } else { - this.stack = ''; - } - } - - /** - * If the error permits, propagate the error to be rendered on screen - */ - displayToScreen() { - throw this; - } -} -// Note, you can't extend the built in Error class: -// http://stackoverflow.com/questions/33870684/why-doesnt-instanceof-work-on-instances-of-error-subclasses-under-babel-node -// Hence we are inheriting from it this way, instead of using extends Error, and this will then preserve -// instanceof checks. -try { - createLegacyClass(KbnError).inherits(Error); -} catch (e) { - // Avoid TypeError: Cannot redefine property: prototype -} - - -/** - * Request Failure - When an entire multi request fails - * @param {Error} err - the Error that came back - * @param {Object} resp - optional HTTP response - */ -export class RequestFailure extends KbnError { - constructor(err, resp) { - err = err || false; - super(`Request to Elasticsearch failed: ${angular.toJson(resp || err.message)}`, - RequestFailure); - - this.origError = err; - this.resp = resp; - } -} - -/** - * FetchFailure Error - when there is an error getting a doc or search within - * a multi-response response body - * @param {Object} resp - The response from es. - */ -export class FetchFailure extends KbnError { - constructor(resp) { - super( - `Failed to get the doc: ${angular.toJson(resp)}`, - FetchFailure); - - this.resp = resp; - } -} - -/** - * A doc was re-indexed but it was out of date. - * @param {Object} resp - The response from es (one of the multi-response responses). - */ -export class VersionConflict extends KbnError { - constructor(resp) { - super( - 'Failed to store document changes do to a version conflict.', - VersionConflict); - - this.resp = resp; - } -} - -/** - * there was a conflict storing a doc - * @param {String} field - the fields which contains the conflict - */ -export class MappingConflict extends KbnError { - constructor(field) { - super( - `Field "${field}" is defined with at least two different types in indices matching the pattern`, - MappingConflict); - } -} - -/** - * a field mapping was using a restricted fields name - * @param {String} field - the fields which contains the conflict - */ -export class RestrictedMapping extends KbnError { - constructor(field, index) { - let msg = `"${field}" is a restricted field name`; - if (index) msg += `, found it while attempting to fetch mapping for index pattern: ${index}`; - - super(msg, RestrictedMapping); - } -} - -/** - * a non-critical cache write to elasticsearch failed - */ -export class CacheWriteFailure extends KbnError { - constructor() { - super( - 'A Elasticsearch cache write has failed.', - CacheWriteFailure); - } -} - -/** - * when a field mapping is requested for an unknown field - * @param {String} name - the field name - */ -export class FieldNotFoundInCache extends KbnError { - constructor(name) { - super( - `The "${name}" field was not found in the cached mappings`, - FieldNotFoundInCache); - } -} - -/** - * when a mapping already exists for a field the user is attempting to add - * @param {String} name - the field name - */ -export class DuplicateField extends KbnError { - constructor(name) { - super( - `The field "${name}" already exists in this mapping`, - DuplicateField); - } -} - -/** - * A saved object was not found - */ -export class SavedObjectNotFound extends KbnError { - constructor(type, id, link) { - const idMsg = id ? ` (id: ${id})` : ''; - let message = `Could not locate that ${type}${idMsg}`; - - if (link) { - message += `, [click here to re-create it](${link})`; - } - - super(message, SavedObjectNotFound); - - this.savedObjectType = type; - this.savedObjectId = id; - } -} - -export class PersistedStateError extends KbnError { - constructor() { - super( - 'Error with the persisted state', - PersistedStateError); - } -} - -/** - * This error is for scenarios where a saved object is detected that has invalid JSON properties. - * There was a scenario where we were importing objects with double-encoded JSON, and the system - * was silently failing. This error is now thrown in those scenarios. - */ -export class InvalidJSONProperty extends KbnError { - constructor(message) { - super(message); - } -} - -/** - * UI Errors - */ -export class VislibError extends KbnError { - constructor(message) { - super(message); - } - - displayToScreen(handler) { - handler.error(this.message); - } -} - -export class ContainerTooSmall extends VislibError { - constructor() { - super('This container is too small to render the visualization'); - } -} - -export class InvalidWiggleSelection extends VislibError { - constructor() { - super('In wiggle mode the area chart requires ordered values on the x-axis. Try using a Histogram or Date Histogram aggregation.'); - } -} - -export class PieContainsAllZeros extends VislibError { - constructor() { - super('No results displayed because all values equal 0.'); - } -} - -export class InvalidLogScaleValues extends VislibError { - constructor() { - super('Values less than 1 cannot be displayed on a log scale'); - } -} - -export class StackedBarChartConfig extends VislibError { - constructor(message) { - super(message); - } -} - -export class NoResults extends VislibError { - constructor() { - super('No results found'); - } -} diff --git a/src/legacy/ui/public/persisted_state/__tests__/persisted_state_provider.js b/src/legacy/ui/public/persisted_state/__tests__/persisted_state_provider.js index 7300bd159337c..df4a7a07471fb 100644 --- a/src/legacy/ui/public/persisted_state/__tests__/persisted_state_provider.js +++ b/src/legacy/ui/public/persisted_state/__tests__/persisted_state_provider.js @@ -22,7 +22,7 @@ import sinon from 'sinon'; import noDigestPromises from 'test_utils/no_digest_promises'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; -import { PersistedStateError } from '../../errors'; +import { PersistedStateError } from '../errors'; import '..'; let PersistedState; diff --git a/src/legacy/ui/public/persisted_state/errors.ts b/src/legacy/ui/public/persisted_state/errors.ts new file mode 100644 index 0000000000000..164981107298d --- /dev/null +++ b/src/legacy/ui/public/persisted_state/errors.ts @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { KbnError } from '../../../../plugins/kibana_utils/public'; + +export class PersistedStateError extends KbnError { + constructor() { + super('Error with the persisted state'); + } +} diff --git a/src/legacy/ui/public/persisted_state/persisted_state.js b/src/legacy/ui/public/persisted_state/persisted_state.js index fb18afc4a726b..d11e44953367a 100644 --- a/src/legacy/ui/public/persisted_state/persisted_state.js +++ b/src/legacy/ui/public/persisted_state/persisted_state.js @@ -25,9 +25,10 @@ import _ from 'lodash'; import toPath from 'lodash/internal/toPath'; -import { PersistedStateError } from '../errors'; +import { PersistedStateError } from './errors'; import { SimpleEmitter } from '../utils/simple_emitter'; + function prepSetParams(key, value, path) { // key must be the value, set the entire state using it if (_.isUndefined(value) && (_.isPlainObject(key) || path.length > 0)) { diff --git a/src/legacy/ui/public/saved_objects/__tests__/saved_object.js b/src/legacy/ui/public/saved_objects/__tests__/saved_object.js index 1c23a9e8f91ee..bb733da193069 100644 --- a/src/legacy/ui/public/saved_objects/__tests__/saved_object.js +++ b/src/legacy/ui/public/saved_objects/__tests__/saved_object.js @@ -25,7 +25,7 @@ import BluebirdPromise from 'bluebird'; import { SavedObjectProvider } from '../saved_object'; import StubIndexPatternProv from 'test_utils/stub_index_pattern'; import { SavedObjectsClientProvider } from '../saved_objects_client_provider'; -import { InvalidJSONProperty } from '../../errors'; +import { InvalidJSONProperty } from '../../../../../plugins/kibana_utils/public'; const getConfig = cfg => cfg; diff --git a/src/legacy/ui/public/saved_objects/saved_object.js b/src/legacy/ui/public/saved_objects/saved_object.js index 74d273119125a..2da1573d503a9 100644 --- a/src/legacy/ui/public/saved_objects/saved_object.js +++ b/src/legacy/ui/public/saved_objects/saved_object.js @@ -31,7 +31,8 @@ import angular from 'angular'; import _ from 'lodash'; -import { InvalidJSONProperty, SavedObjectNotFound } from '../errors'; + +import { InvalidJSONProperty, SavedObjectNotFound } from '../../../../plugins/kibana_utils/public'; import { expandShorthand } from '../utils/mapping_setup'; import { SearchSourceProvider } from '../courier/search_source'; diff --git a/src/legacy/ui/public/url/redirect_when_missing.js b/src/legacy/ui/public/url/redirect_when_missing.js index 5fd8611dbcde9..cd96cb6cbaeb9 100644 --- a/src/legacy/ui/public/url/redirect_when_missing.js +++ b/src/legacy/ui/public/url/redirect_when_missing.js @@ -22,7 +22,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { MarkdownSimple } from '../../../core_plugins/kibana_react/public/markdown'; import { toastNotifications } from 'ui/notify'; -import { SavedObjectNotFound } from '../errors'; +import { SavedObjectNotFound } from '../../../../plugins/kibana_utils/public'; import { uiModules } from '../modules'; uiModules.get('kibana/url') diff --git a/src/legacy/ui/public/vislib/errors.ts b/src/legacy/ui/public/vislib/errors.ts new file mode 100644 index 0000000000000..0c6e720f0ef32 --- /dev/null +++ b/src/legacy/ui/public/vislib/errors.ts @@ -0,0 +1,56 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* eslint-disable max-classes-per-file */ + +import { KbnError } from '../../../../plugins/kibana_utils/public'; + +export class VislibError extends KbnError { + constructor(message: string) { + super(message); + } + + displayToScreen(handler: any) { + handler.error(this.message); + } +} + +export class InvalidLogScaleValues extends VislibError { + constructor() { + super('Values less than 1 cannot be displayed on a log scale'); + } +} + +export class ContainerTooSmall extends VislibError { + constructor() { + super('This container is too small to render the visualization'); + } +} + +export class PieContainsAllZeros extends VislibError { + constructor() { + super('No results displayed because all values equal 0.'); + } +} + +export class NoResults extends VislibError { + constructor() { + super('No results found'); + } +} diff --git a/src/legacy/ui/public/vislib/lib/_error_handler.js b/src/legacy/ui/public/vislib/lib/_error_handler.js index 8ec5e9d47c2a0..7f9a927242c7c 100644 --- a/src/legacy/ui/public/vislib/lib/_error_handler.js +++ b/src/legacy/ui/public/vislib/lib/_error_handler.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import { ContainerTooSmall } from '../../errors'; +import { ContainerTooSmall } from '../errors'; /** * Common errors shared between constructors diff --git a/src/legacy/ui/public/vislib/lib/axis/axis.js b/src/legacy/ui/public/vislib/lib/axis/axis.js index b93b1ae088f5e..79508c39712aa 100644 --- a/src/legacy/ui/public/vislib/lib/axis/axis.js +++ b/src/legacy/ui/public/vislib/lib/axis/axis.js @@ -25,7 +25,7 @@ import { AxisTitle } from './axis_title'; import { AxisLabels } from './axis_labels'; import { AxisScale } from './axis_scale'; import { AxisConfig } from './axis_config'; -import { VislibError } from '../../../errors'; +import { VislibError } from '../../errors'; export class Axis extends ErrorHandler { constructor(visConfig, axisConfigArgs) { diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js b/src/legacy/ui/public/vislib/lib/axis/axis_scale.js index 836d27441d1ae..9fdb79a287cb7 100644 --- a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js +++ b/src/legacy/ui/public/vislib/lib/axis/axis_scale.js @@ -21,9 +21,10 @@ import d3 from 'd3'; import _ from 'lodash'; import moment from 'moment'; -import { InvalidLogScaleValues } from '../../../errors'; +import { InvalidLogScaleValues } from '../../errors'; import { timeTicks } from './time_ticks'; + export class AxisScale { constructor(axisConfig, visConfig) { this.axisConfig = axisConfig; diff --git a/src/legacy/ui/public/vislib/lib/handler.js b/src/legacy/ui/public/vislib/lib/handler.js index a289e15456351..5c95113530904 100644 --- a/src/legacy/ui/public/vislib/lib/handler.js +++ b/src/legacy/ui/public/vislib/lib/handler.js @@ -20,7 +20,7 @@ import d3 from 'd3'; import _ from 'lodash'; import MarkdownIt from 'markdown-it'; -import { NoResults } from '../../errors'; +import { NoResults } from '../errors'; import { Binder } from '../../binder'; import { Layout } from './layout/layout'; import { ChartTitle } from './chart_title'; diff --git a/src/legacy/ui/public/vislib/vis.js b/src/legacy/ui/public/vislib/vis.js index d6bb70dba4b4f..5187d6f1d1124 100644 --- a/src/legacy/ui/public/vislib/vis.js +++ b/src/legacy/ui/public/vislib/vis.js @@ -21,7 +21,7 @@ import _ from 'lodash'; import d3 from 'd3'; import { EventEmitter } from 'events'; import chrome from '../chrome'; -import { KbnError } from '../errors'; +import { VislibError } from './errors'; import { VisConfig } from './lib/vis_config'; import { Handler } from './lib/handler'; import { setHierarchicalTooltipFormatter } from '../vis/components/tooltip/_hierarchical_tooltip_formatter'; @@ -98,7 +98,7 @@ export function VislibVisProvider(Private) { this.handler[method](); } catch (error) { - if (error instanceof KbnError) { + if (error instanceof VislibError) { error.displayToScreen(this.handler); } else { throw error; diff --git a/src/legacy/ui/public/vislib/visualizations/pie_chart.js b/src/legacy/ui/public/vislib/visualizations/pie_chart.js index c42c347a18f9a..8f9d180de654d 100644 --- a/src/legacy/ui/public/vislib/visualizations/pie_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/pie_chart.js @@ -21,7 +21,7 @@ import d3 from 'd3'; import _ from 'lodash'; import $ from 'jquery'; import numeral from 'numeral'; -import { PieContainsAllZeros, ContainerTooSmall } from '../../errors'; +import { PieContainsAllZeros, ContainerTooSmall } from '../errors'; import { Chart } from './_chart'; import { truncateLabel } from '../components/labels/truncate_labels'; diff --git a/src/legacy/ui/public/__tests__/errors.js b/src/plugins/kibana_utils/public/errors/errors.test.ts similarity index 52% rename from src/legacy/ui/public/__tests__/errors.js rename to src/plugins/kibana_utils/public/errors/errors.test.ts index 6387abbf60369..fa769e71c250e 100644 --- a/src/legacy/ui/public/__tests__/errors.js +++ b/src/plugins/kibana_utils/public/errors/errors.test.ts @@ -18,47 +18,10 @@ */ import expect from '@kbn/expect'; -import { - RequestFailure, - FetchFailure, - VersionConflict, - MappingConflict, - RestrictedMapping, - CacheWriteFailure, - FieldNotFoundInCache, - DuplicateField, - SavedObjectNotFound, - PersistedStateError, - VislibError, - ContainerTooSmall, - InvalidWiggleSelection, - PieContainsAllZeros, - InvalidLogScaleValues, - StackedBarChartConfig, - NoResults, - KbnError -} from '../errors'; +import { DuplicateField, SavedObjectNotFound, KbnError } from './errors'; -describe('ui/errors', () => { - const errors = [ - new RequestFailure('an error', { }), - new FetchFailure({ }), - new VersionConflict({ }), - new MappingConflict({ }), - new RestrictedMapping('field', 'indexPattern'), - new CacheWriteFailure(), - new FieldNotFoundInCache('aname'), - new DuplicateField('dupfield'), - new SavedObjectNotFound('dashboard', '123'), - new PersistedStateError(), - new VislibError('err'), - new ContainerTooSmall(), - new InvalidWiggleSelection(), - new PieContainsAllZeros(), - new InvalidLogScaleValues(), - new StackedBarChartConfig('err'), - new NoResults() - ]; +describe('errors', () => { + const errors = [new DuplicateField('dupfield'), new SavedObjectNotFound('dashboard', '123')]; errors.forEach(error => { const className = error.constructor.name; @@ -70,7 +33,7 @@ describe('ui/errors', () => { expect(error.stack).to.not.be.empty(); }); - it (`${className} is an instance of KbnError`, () => { + it(`${className} is an instance of KbnError`, () => { expect(error instanceof KbnError).to.be(true); }); }); diff --git a/src/plugins/kibana_utils/public/errors/errors.ts b/src/plugins/kibana_utils/public/errors/errors.ts new file mode 100644 index 0000000000000..5842457168d72 --- /dev/null +++ b/src/plugins/kibana_utils/public/errors/errors.ts @@ -0,0 +1,70 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* eslint-disable max-classes-per-file */ + +// abstract error class +export class KbnError extends Error { + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + } +} + +/** + * when a mapping already exists for a field the user is attempting to add + * @param {String} name - the field name + */ +export class DuplicateField extends KbnError { + constructor(name: string) { + super(`The field "${name}" already exists in this mapping`); + } +} + +/** + * A saved object was not found + */ +export class SavedObjectNotFound extends KbnError { + public savedObjectType: string; + public savedObjectId?: string; + constructor(type: string, id?: string, link?: string) { + const idMsg = id ? ` (id: ${id})` : ''; + let message = `Could not locate that ${type}${idMsg}`; + + if (link) { + message += `, [click here to re-create it](${link})`; + } + + super(message); + + this.savedObjectType = type; + this.savedObjectId = id; + } +} + +/** + * This error is for scenarios where a saved object is detected that has invalid JSON properties. + * There was a scenario where we were importing objects with double-encoded JSON, and the system + * was silently failing. This error is now thrown in those scenarios. + */ +export class InvalidJSONProperty extends KbnError { + constructor(message: string) { + super(message); + } +} diff --git a/src/plugins/kibana_utils/public/errors/index.ts b/src/plugins/kibana_utils/public/errors/index.ts new file mode 100644 index 0000000000000..8764f468c5333 --- /dev/null +++ b/src/plugins/kibana_utils/public/errors/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './errors'; diff --git a/src/plugins/kibana_utils/public/index.ts b/src/plugins/kibana_utils/public/index.ts index 2decfbbc5101b..96b5e7a03ffa0 100644 --- a/src/plugins/kibana_utils/public/index.ts +++ b/src/plugins/kibana_utils/public/index.ts @@ -19,3 +19,4 @@ export * from './store'; export * from './parse'; +export * from './errors'; diff --git a/x-pack/legacy/plugins/ml/public/util/ml_error.js b/x-pack/legacy/plugins/ml/public/util/ml_error.js index b040c397fa626..d5a3507ffaa15 100644 --- a/x-pack/legacy/plugins/ml/public/util/ml_error.js +++ b/x-pack/legacy/plugins/ml/public/util/ml_error.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { KbnError } from 'ui/errors'; +import { KbnError } from '../../../../../../src/plugins/kibana_utils/public'; export class MLRequestFailure extends KbnError { // takes an Error object and and optional response object