From 4971a2c772317ed8092ca8f35e539fe71b828b3b Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Tue, 21 Jan 2020 12:58:40 +0100 Subject: [PATCH] Expose fatalErrors API from the Start contract (#55300) * Expose FatalErrors from the Start contract. This API is intended to be used for runtime as well. * update docs * update data plugin snapshot to fix tests * address comments Co-authored-by: Elastic Machine --- ...ana-plugin-public.chromenavlinks.update.md | 60 +++++++++---------- ...ana-plugin-public.corestart.fatalerrors.md | 13 ++++ .../public/kibana-plugin-public.corestart.md | 1 + .../kibana-plugin-public.fatalerrorsstart.md | 13 ++++ .../core/public/kibana-plugin-public.md | 1 + src/core/public/core_system.ts | 2 + .../fatal_errors/fatal_errors_service.mock.ts | 4 ++ .../fatal_errors/fatal_errors_service.tsx | 23 ++++++- src/core/public/fatal_errors/index.ts | 2 +- src/core/public/index.ts | 5 +- src/core/public/legacy/legacy_service.test.ts | 2 + src/core/public/mocks.ts | 1 + src/core/public/plugins/plugin_context.ts | 1 + .../public/plugins/plugins_service.test.ts | 1 + src/core/public/public.api.md | 5 ++ .../query_string_input.test.tsx.snap | 24 ++++++++ 16 files changed, 123 insertions(+), 35 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-public.corestart.fatalerrors.md create mode 100644 docs/development/core/public/kibana-plugin-public.fatalerrorsstart.md diff --git a/docs/development/core/public/kibana-plugin-public.chromenavlinks.update.md b/docs/development/core/public/kibana-plugin-public.chromenavlinks.update.md index d1cd2d3b0495..155d149f334a 100644 --- a/docs/development/core/public/kibana-plugin-public.chromenavlinks.update.md +++ b/docs/development/core/public/kibana-plugin-public.chromenavlinks.update.md @@ -1,30 +1,30 @@ - - -[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [ChromeNavLinks](./kibana-plugin-public.chromenavlinks.md) > [update](./kibana-plugin-public.chromenavlinks.update.md) - -## ChromeNavLinks.update() method - -> Warning: This API is now obsolete. -> -> Uses the [AppBase.updater$](./kibana-plugin-public.appbase.updater_.md) property when registering your application with [ApplicationSetup.register()](./kibana-plugin-public.applicationsetup.register.md) instead. -> - -Update the navlink for the given id with the updated attributes. Returns the updated navlink or `undefined` if it does not exist. - -Signature: - -```typescript -update(id: string, values: ChromeNavLinkUpdateableFields): ChromeNavLink | undefined; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| id | string | | -| values | ChromeNavLinkUpdateableFields | | - -Returns: - -`ChromeNavLink | undefined` - + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [ChromeNavLinks](./kibana-plugin-public.chromenavlinks.md) > [update](./kibana-plugin-public.chromenavlinks.update.md) + +## ChromeNavLinks.update() method + +> Warning: This API is now obsolete. +> +> Uses the [AppBase.updater$](./kibana-plugin-public.appbase.updater_.md) property when registering your application with [ApplicationSetup.register()](./kibana-plugin-public.applicationsetup.register.md) instead. +> + +Update the navlink for the given id with the updated attributes. Returns the updated navlink or `undefined` if it does not exist. + +Signature: + +```typescript +update(id: string, values: ChromeNavLinkUpdateableFields): ChromeNavLink | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | +| values | ChromeNavLinkUpdateableFields | | + +Returns: + +`ChromeNavLink | undefined` + diff --git a/docs/development/core/public/kibana-plugin-public.corestart.fatalerrors.md b/docs/development/core/public/kibana-plugin-public.corestart.fatalerrors.md new file mode 100644 index 000000000000..540b17b5a6f0 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.corestart.fatalerrors.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [CoreStart](./kibana-plugin-public.corestart.md) > [fatalErrors](./kibana-plugin-public.corestart.fatalerrors.md) + +## CoreStart.fatalErrors property + +[FatalErrorsStart](./kibana-plugin-public.fatalerrorsstart.md) + +Signature: + +```typescript +fatalErrors: FatalErrorsStart; +``` diff --git a/docs/development/core/public/kibana-plugin-public.corestart.md b/docs/development/core/public/kibana-plugin-public.corestart.md index e561ee313f10..83af82d590c3 100644 --- a/docs/development/core/public/kibana-plugin-public.corestart.md +++ b/docs/development/core/public/kibana-plugin-public.corestart.md @@ -19,6 +19,7 @@ export interface CoreStart | [application](./kibana-plugin-public.corestart.application.md) | ApplicationStart | [ApplicationStart](./kibana-plugin-public.applicationstart.md) | | [chrome](./kibana-plugin-public.corestart.chrome.md) | ChromeStart | [ChromeStart](./kibana-plugin-public.chromestart.md) | | [docLinks](./kibana-plugin-public.corestart.doclinks.md) | DocLinksStart | [DocLinksStart](./kibana-plugin-public.doclinksstart.md) | +| [fatalErrors](./kibana-plugin-public.corestart.fatalerrors.md) | FatalErrorsStart | [FatalErrorsStart](./kibana-plugin-public.fatalerrorsstart.md) | | [http](./kibana-plugin-public.corestart.http.md) | HttpStart | [HttpStart](./kibana-plugin-public.httpstart.md) | | [i18n](./kibana-plugin-public.corestart.i18n.md) | I18nStart | [I18nStart](./kibana-plugin-public.i18nstart.md) | | [injectedMetadata](./kibana-plugin-public.corestart.injectedmetadata.md) | {
getInjectedVar: (name: string, defaultValue?: any) => unknown;
} | exposed temporarily until https://github.com/elastic/kibana/issues/41990 done use \*only\* to retrieve config values. There is no way to set injected values in the new platform. Use the legacy platform API instead. | diff --git a/docs/development/core/public/kibana-plugin-public.fatalerrorsstart.md b/docs/development/core/public/kibana-plugin-public.fatalerrorsstart.md new file mode 100644 index 000000000000..a8ece7dcb7e0 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.fatalerrorsstart.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [FatalErrorsStart](./kibana-plugin-public.fatalerrorsstart.md) + +## FatalErrorsStart type + +FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. + +Signature: + +```typescript +export declare type FatalErrorsStart = FatalErrorsSetup; +``` diff --git a/docs/development/core/public/kibana-plugin-public.md b/docs/development/core/public/kibana-plugin-public.md index 27ca9f2d9fd5..27037d46926c 100644 --- a/docs/development/core/public/kibana-plugin-public.md +++ b/docs/development/core/public/kibana-plugin-public.md @@ -129,6 +129,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ChromeHelpExtensionMenuGitHubLink](./kibana-plugin-public.chromehelpextensionmenugithublink.md) | | | [ChromeHelpExtensionMenuLink](./kibana-plugin-public.chromehelpextensionmenulink.md) | | | [ChromeNavLinkUpdateableFields](./kibana-plugin-public.chromenavlinkupdateablefields.md) | | +| [FatalErrorsStart](./kibana-plugin-public.fatalerrorsstart.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | | [HandlerContextType](./kibana-plugin-public.handlercontexttype.md) | Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-public.handlerfunction.md) to represent the type of the context. | | [HandlerFunction](./kibana-plugin-public.handlerfunction.md) | A function that accepts a context object and an optional number of additional arguments. Used for the generic types in [IContextContainer](./kibana-plugin-public.icontextcontainer.md) | | [HandlerParameters](./kibana-plugin-public.handlerparameters.md) | Extracts the types of the additional arguments of a [HandlerFunction](./kibana-plugin-public.handlerfunction.md), excluding the [HandlerContextType](./kibana-plugin-public.handlercontexttype.md). | diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 5b31c740518e..97bd49416f70 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -214,6 +214,7 @@ export class CoreSystem { const http = await this.http.start({ injectedMetadata, fatalErrors: this.fatalErrorsSetup! }); const savedObjects = await this.savedObjects.start({ http }); const i18n = await this.i18n.start(); + const fatalErrors = await this.fatalErrors.start(); await this.integrations.start({ uiSettings }); const coreUiTargetDomElement = document.createElement('div'); @@ -271,6 +272,7 @@ export class CoreSystem { notifications, overlays, uiSettings, + fatalErrors, }; const plugins = await this.plugins.start(core); diff --git a/src/core/public/fatal_errors/fatal_errors_service.mock.ts b/src/core/public/fatal_errors/fatal_errors_service.mock.ts index dd7702a7ee7d..6d9876f787fa 100644 --- a/src/core/public/fatal_errors/fatal_errors_service.mock.ts +++ b/src/core/public/fatal_errors/fatal_errors_service.mock.ts @@ -26,18 +26,22 @@ const createSetupContractMock = () => { return setupContract; }; +const createStartContractMock = createSetupContractMock; type FatalErrorsServiceContract = PublicMethodsOf; const createMock = () => { const mocked: jest.Mocked = { setup: jest.fn(), + start: jest.fn(), }; mocked.setup.mockReturnValue(createSetupContractMock()); + mocked.start.mockReturnValue(createStartContractMock()); return mocked; }; export const fatalErrorsServiceMock = { create: createMock, createSetupContract: createSetupContractMock, + createStartContract: createStartContractMock, }; diff --git a/src/core/public/fatal_errors/fatal_errors_service.tsx b/src/core/public/fatal_errors/fatal_errors_service.tsx index 5c6a7bb322ae..309f07859ef2 100644 --- a/src/core/public/fatal_errors/fatal_errors_service.tsx +++ b/src/core/public/fatal_errors/fatal_errors_service.tsx @@ -54,9 +54,18 @@ export interface FatalErrorsSetup { get$: () => Rx.Observable; } +/** + * FatalErrors stop the Kibana Public Core and displays a fatal error screen + * with details about the Kibana build and the error. + * + * @public + */ +export type FatalErrorsStart = FatalErrorsSetup; + /** @interal */ export class FatalErrorsService { private readonly errorInfo$ = new Rx.ReplaySubject(); + private fatalErrors?: FatalErrorsSetup; /** * @@ -82,7 +91,7 @@ export class FatalErrorsService { }, }); - const fatalErrorsSetup: FatalErrorsSetup = { + this.fatalErrors = { add: (error, source?) => { const errorInfo = getErrorInfo(error, source); @@ -101,9 +110,17 @@ export class FatalErrorsService { }, }; - this.setupGlobalErrorHandlers(fatalErrorsSetup); + this.setupGlobalErrorHandlers(this.fatalErrors!); - return fatalErrorsSetup; + return this.fatalErrors!; + } + + public start() { + const { fatalErrors } = this; + if (!fatalErrors) { + throw new Error('FatalErrorsService#setup() must be invoked before start.'); + } + return fatalErrors; } private renderError(injectedMetadata: InjectedMetadataSetup, i18n: I18nStart) { diff --git a/src/core/public/fatal_errors/index.ts b/src/core/public/fatal_errors/index.ts index e37a36152cf9..c8ea1c0bccd2 100644 --- a/src/core/public/fatal_errors/index.ts +++ b/src/core/public/fatal_errors/index.ts @@ -17,5 +17,5 @@ * under the License. */ -export { FatalErrorsSetup, FatalErrorsService } from './fatal_errors_service'; +export { FatalErrorsSetup, FatalErrorsStart, FatalErrorsService } from './fatal_errors_service'; export { FatalErrorInfo } from './get_error_info'; diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 5b17eccc37f8..5e732dd05e61 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -55,7 +55,7 @@ import { ChromeRecentlyAccessed, ChromeRecentlyAccessedHistoryItem, } from './chrome'; -import { FatalErrorsSetup, FatalErrorInfo } from './fatal_errors'; +import { FatalErrorsSetup, FatalErrorsStart, FatalErrorInfo } from './fatal_errors'; import { HttpSetup, HttpStart } from './http'; import { I18nStart } from './i18n'; import { InjectedMetadataSetup, InjectedMetadataStart, LegacyNavLink } from './injected_metadata'; @@ -232,6 +232,8 @@ export interface CoreStart { overlays: OverlayStart; /** {@link IUiSettingsClient} */ uiSettings: IUiSettingsClient; + /** {@link FatalErrorsStart} */ + fatalErrors: FatalErrorsStart; /** * exposed temporarily until https://github.com/elastic/kibana/issues/41990 done * use *only* to retrieve config values. There is no way to set injected values @@ -302,6 +304,7 @@ export { DocLinksStart, FatalErrorInfo, FatalErrorsSetup, + FatalErrorsStart, HttpSetup, HttpStart, I18nStart, diff --git a/src/core/public/legacy/legacy_service.test.ts b/src/core/public/legacy/legacy_service.test.ts index 9dd24f9e4a7a..d08c8b52e39c 100644 --- a/src/core/public/legacy/legacy_service.test.ts +++ b/src/core/public/legacy/legacy_service.test.ts @@ -98,6 +98,7 @@ const notificationsStart = notificationServiceMock.createStartContract(); const overlayStart = overlayServiceMock.createStartContract(); const uiSettingsStart = uiSettingsServiceMock.createStartContract(); const savedObjectsStart = savedObjectsMock.createStartContract(); +const fatalErrorsStart = fatalErrorsServiceMock.createStartContract(); const mockStorage = { getItem: jest.fn() } as any; const defaultStartDeps = { @@ -112,6 +113,7 @@ const defaultStartDeps = { overlays: overlayStart, uiSettings: uiSettingsStart, savedObjects: savedObjectsStart, + fatalErrors: fatalErrorsStart, }, lastSubUrlStorage: mockStorage, targetDomElement: document.createElement('div'), diff --git a/src/core/public/mocks.ts b/src/core/public/mocks.ts index 43c8aa6f1d6b..ce90d49065ad 100644 --- a/src/core/public/mocks.ts +++ b/src/core/public/mocks.ts @@ -74,6 +74,7 @@ function createCoreStartMock({ basePath = '' } = {}) { injectedMetadata: { getInjectedVar: injectedMetadataServiceMock.createStartContract().getInjectedVar, }, + fatalErrors: fatalErrorsServiceMock.createStartContract(), }; return mock; diff --git a/src/core/public/plugins/plugin_context.ts b/src/core/public/plugins/plugin_context.ts index f146c2452868..48100cba4f26 100644 --- a/src/core/public/plugins/plugin_context.ts +++ b/src/core/public/plugins/plugin_context.ts @@ -151,5 +151,6 @@ export function createPluginStartContext< injectedMetadata: { getInjectedVar: deps.injectedMetadata.getInjectedVar, }, + fatalErrors: deps.fatalErrors, }; } diff --git a/src/core/public/plugins/plugins_service.test.ts b/src/core/public/plugins/plugins_service.test.ts index cafc7e5887e3..dbbcda8d60e1 100644 --- a/src/core/public/plugins/plugins_service.test.ts +++ b/src/core/public/plugins/plugins_service.test.ts @@ -111,6 +111,7 @@ describe('PluginsService', () => { overlays: overlayServiceMock.createStartContract(), uiSettings: uiSettingsServiceMock.createStartContract(), savedObjects: savedObjectsMock.createStartContract(), + fatalErrors: fatalErrorsServiceMock.createStartContract(), }; mockStartContext = { ...mockStartDeps, diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index abd39e864bd3..f7b260c68ee9 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -377,6 +377,8 @@ export interface CoreStart { // (undocumented) docLinks: DocLinksStart; // (undocumented) + fatalErrors: FatalErrorsStart; + // (undocumented) http: HttpStart; // (undocumented) i18n: I18nStart; @@ -532,6 +534,9 @@ export interface FatalErrorsSetup { get$: () => Rx.Observable; } +// @public +export type FatalErrorsStart = FatalErrorsSetup; + // @public export type HandlerContextType> = T extends HandlerFunction ? U : never; diff --git a/src/plugins/data/public/ui/query_string_input/__snapshots__/query_string_input.test.tsx.snap b/src/plugins/data/public/ui/query_string_input/__snapshots__/query_string_input.test.tsx.snap index bc08c87304fc..d8db53d4c602 100644 --- a/src/plugins/data/public/ui/query_string_input/__snapshots__/query_string_input.test.tsx.snap +++ b/src/plugins/data/public/ui/query_string_input/__snapshots__/query_string_input.test.tsx.snap @@ -304,6 +304,10 @@ exports[`QueryStringInput Should disable autoFocus on EuiFieldText when disableA }, }, }, + "fatalErrors": Object { + "add": [MockFunction], + "get$": [MockFunction], + }, "http": Object { "addLoadingCountSource": [MockFunction], "anonymousPaths": Object { @@ -930,6 +934,10 @@ exports[`QueryStringInput Should disable autoFocus on EuiFieldText when disableA }, }, }, + "fatalErrors": Object { + "add": [MockFunction], + "get$": [MockFunction], + }, "http": Object { "addLoadingCountSource": [MockFunction], "anonymousPaths": Object { @@ -1538,6 +1546,10 @@ exports[`QueryStringInput Should pass the query language to the language switche }, }, }, + "fatalErrors": Object { + "add": [MockFunction], + "get$": [MockFunction], + }, "http": Object { "addLoadingCountSource": [MockFunction], "anonymousPaths": Object { @@ -2161,6 +2173,10 @@ exports[`QueryStringInput Should pass the query language to the language switche }, }, }, + "fatalErrors": Object { + "add": [MockFunction], + "get$": [MockFunction], + }, "http": Object { "addLoadingCountSource": [MockFunction], "anonymousPaths": Object { @@ -2769,6 +2785,10 @@ exports[`QueryStringInput Should render the given query 1`] = ` }, }, }, + "fatalErrors": Object { + "add": [MockFunction], + "get$": [MockFunction], + }, "http": Object { "addLoadingCountSource": [MockFunction], "anonymousPaths": Object { @@ -3392,6 +3412,10 @@ exports[`QueryStringInput Should render the given query 1`] = ` }, }, }, + "fatalErrors": Object { + "add": [MockFunction], + "get$": [MockFunction], + }, "http": Object { "addLoadingCountSource": [MockFunction], "anonymousPaths": Object {