From fa3b8c0207e4d5d5f4d828f883dad5c7a77938f4 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 2 Jun 2020 12:04:08 +0200 Subject: [PATCH] use properly typed errors for obs --- .../global_search/common/errors.test.ts | 22 +++++++++++++++ x-pack/plugins/global_search/common/errors.ts | 27 +++++++++++++++++++ .../public/services/search_service.ts | 5 +++- .../global_search/server/routes/find.ts | 6 ++++- .../server/services/search_service.ts | 5 +++- 5 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugins/global_search/common/errors.test.ts create mode 100644 x-pack/plugins/global_search/common/errors.ts diff --git a/x-pack/plugins/global_search/common/errors.test.ts b/x-pack/plugins/global_search/common/errors.test.ts new file mode 100644 index 000000000000..949795abd701 --- /dev/null +++ b/x-pack/plugins/global_search/common/errors.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { GlobalSearchFindError } from './errors'; + +describe('GlobalSearchFindError', () => { + describe('#invalidLicense', () => { + it('create an error with the correct `type`', () => { + const error = GlobalSearchFindError.invalidLicense('foobar'); + expect(error.message).toBe('foobar'); + expect(error.type).toBe('invalid-license'); + }); + + it('can be identified via instanceof', () => { + const error = GlobalSearchFindError.invalidLicense('foo'); + expect(error instanceof GlobalSearchFindError).toBe(true); + }); + }); +}); diff --git a/x-pack/plugins/global_search/common/errors.ts b/x-pack/plugins/global_search/common/errors.ts new file mode 100644 index 000000000000..15bc0958cb8a --- /dev/null +++ b/x-pack/plugins/global_search/common/errors.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// only one type for now, but already present for future-proof reasons +export type GlobalSearchFindErrorType = 'invalid-license'; + +/** + * Error thrown from the {@link GlobalSearchPluginStart.find | GlobalSearch find API}'s result observable + * + * @public + */ +export class GlobalSearchFindError extends Error { + public static invalidLicense(message: string) { + return new GlobalSearchFindError('invalid-license', message); + } + + private constructor(public readonly type: GlobalSearchFindErrorType, message: string) { + super(message); + + // Set the prototype explicitly, see: + // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work + Object.setPrototypeOf(this, GlobalSearchFindError.prototype); + } +} diff --git a/x-pack/plugins/global_search/public/services/search_service.ts b/x-pack/plugins/global_search/public/services/search_service.ts index 7589813d31cb..71742a1173a5 100644 --- a/x-pack/plugins/global_search/public/services/search_service.ts +++ b/x-pack/plugins/global_search/public/services/search_service.ts @@ -9,6 +9,7 @@ import { map, takeUntil } from 'rxjs/operators'; import { duration } from 'moment'; import { HttpStart, ApplicationStart } from 'src/core/public'; import { GlobalSearchProviderResult } from '../../common/types'; +import { GlobalSearchFindError } from '../../common/errors'; import { takeInArray } from '../../common/operators'; import { processProviderResult } from '../../common/process_result'; import { ILicenseChecker } from '../../common/license_checker'; @@ -82,7 +83,9 @@ export class SearchService { const licenseState = this.licenseChecker!.getState(); if (!licenseState.valid) { return throwError( - `GlobalSearch API is disabled because of invalid license state: ${licenseState.message}` + GlobalSearchFindError.invalidLicense( + `GlobalSearch API is disabled because of invalid license state: ${licenseState.message}` + ) ); } diff --git a/x-pack/plugins/global_search/server/routes/find.ts b/x-pack/plugins/global_search/server/routes/find.ts index 193157b56acb..a9063abda0e3 100644 --- a/x-pack/plugins/global_search/server/routes/find.ts +++ b/x-pack/plugins/global_search/server/routes/find.ts @@ -7,6 +7,7 @@ import { reduce, map } from 'rxjs/operators'; import { schema } from '@kbn/config-schema'; import { IRouter } from 'src/core/server'; +import { GlobalSearchFindError } from '../../common/errors'; export const registerInternalFindRoute = (router: IRouter) => { router.post( @@ -39,7 +40,10 @@ export const registerInternalFindRoute = (router: IRouter) => { }, }); } catch (e) { - return res.forbidden({ body: e }); + if (e instanceof GlobalSearchFindError && e.type === 'invalid-license') { + return res.forbidden({ body: e.message }); + } + throw e; } } ); diff --git a/x-pack/plugins/global_search/server/services/search_service.ts b/x-pack/plugins/global_search/server/services/search_service.ts index 45721f1fb256..9f524510e0c0 100644 --- a/x-pack/plugins/global_search/server/services/search_service.ts +++ b/x-pack/plugins/global_search/server/services/search_service.ts @@ -8,6 +8,7 @@ import { Observable, timer, merge, throwError } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; import { KibanaRequest, CoreStart, IBasePath } from 'src/core/server'; import { GlobalSearchProviderResult } from '../../common/types'; +import { GlobalSearchFindError } from '../../common/errors'; import { takeInArray } from '../../common/operators'; import { ILicenseChecker } from '../../common/license_checker'; @@ -84,7 +85,9 @@ export class SearchService { const licenseState = this.licenseChecker!.getState(); if (!licenseState.valid) { return throwError( - `GlobalSearch API is disabled because of invalid license state: ${licenseState.message}` + GlobalSearchFindError.invalidLicense( + `GlobalSearch API is disabled because of invalid license state: ${licenseState.message}` + ) ); }