From 18dad948a10a2034959e1eb14b3c41669683e1fb Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 20 Jun 2022 15:46:06 +0200 Subject: [PATCH 01/13] add custom search error Signed-off-by: Emma Indal --- plugins/search-backend-node/src/errors.ts | 23 +++++++++++++++++++++++ plugins/search-backend-node/src/index.ts | 1 + 2 files changed, 24 insertions(+) create mode 100644 plugins/search-backend-node/src/errors.ts diff --git a/plugins/search-backend-node/src/errors.ts b/plugins/search-backend-node/src/errors.ts new file mode 100644 index 0000000000..c6128f3f2e --- /dev/null +++ b/plugins/search-backend-node/src/errors.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed 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 { CustomErrorBase } from '@backstage/errors'; + +/** + * Failed to query documents for index that does not exist. + * @public + */ +export class MissingIndexError extends CustomErrorBase {} diff --git a/plugins/search-backend-node/src/index.ts b/plugins/search-backend-node/src/index.ts index d342bb9259..854881829c 100644 --- a/plugins/search-backend-node/src/index.ts +++ b/plugins/search-backend-node/src/index.ts @@ -34,6 +34,7 @@ export type { RegisterCollatorParameters, RegisterDecoratorParameters, } from './types'; +export * from './errors'; export * from './indexing'; export * from './test-utils'; From c30ecd900f75cfc74a48f14f74bc663bd6121f60 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 20 Jun 2022 15:48:44 +0200 Subject: [PATCH 02/13] ElasticSearch engine throw MissingIndexError if error type is index_not_found_exception Signed-off-by: Emma Indal --- .../src/engines/ElasticSearchSearchEngine.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts index 31112e3446..8f321a266c 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts @@ -26,6 +26,7 @@ import { SearchEngine, SearchQuery, } from '@backstage/plugin-search-common'; +import { MissingIndexError } from '@backstage/plugin-search-backend-node'; import { Client } from '@elastic/elasticsearch'; import esb from 'elastic-builder'; import { isEmpty, isNaN as nan, isNumber } from 'lodash'; @@ -362,6 +363,9 @@ export class ElasticSearchSearchEngine implements SearchEngine { previousPageCursor, }; } catch (e) { + if (e.meta.body.error.type === 'index_not_found_exception') { + throw new MissingIndexError(`Missing index for ${queryIndices}`, e); + } this.logger.error( `Failed to query documents for indices ${queryIndices}`, e, From 1e28c4336632edf6814e66ee5bb05406c0e8e560 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 20 Jun 2022 16:24:15 +0200 Subject: [PATCH 03/13] check error, if MissingIndexError return status code 400 with clear error message Signed-off-by: Emma Indal --- plugins/search-backend/src/service/router.ts | 24 ++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index f54c2d388f..c85b3ed797 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -33,7 +33,10 @@ import { IndexableResultSet, SearchResultSet, } from '@backstage/plugin-search-common'; -import { SearchEngine } from '@backstage/plugin-search-backend-node'; +import { + SearchEngine, + MissingIndexError, +} from '@backstage/plugin-search-backend-node'; import { AuthorizedSearchEngine } from './AuthorizedSearchEngine'; const jsonObjectSchema: z.ZodSchema = z.lazy(() => { @@ -129,7 +132,10 @@ export async function createRouter( const router = Router(); router.get( '/query', - async (req: express.Request, res: express.Response) => { + async ( + req: express.Request, + res: express.Response, + ) => { const parseResult = requestSchema.safeParse(req.query); if (!parseResult.success) { @@ -154,9 +160,19 @@ export async function createRouter( const resultSet = await engine?.query(query, { token }); res.send(filterResultSet(toSearchResults(resultSet))); - } catch (err) { + } catch (error) { + if (error instanceof MissingIndexError) { + res + .status(400) + .send( + `\nNo index found for types: ${ + query.types ? query.types.join(',') : '' + }. This means there are no documents to search through.`, + ); + } + throw new Error( - `There was a problem performing the search query. ${err}`, + `There was a problem performing the search query. ${error}`, ); } }, From 741b6df63a59b721a6422dbecf89863f840c7e9f Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Tue, 21 Jun 2022 10:02:04 +0200 Subject: [PATCH 04/13] update api reports Signed-off-by: Emma Indal --- plugins/search-backend-node/api-report.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/search-backend-node/api-report.md b/plugins/search-backend-node/api-report.md index 7649bc5d0f..63273d7514 100644 --- a/plugins/search-backend-node/api-report.md +++ b/plugins/search-backend-node/api-report.md @@ -6,6 +6,7 @@ /// import { Config } from '@backstage/config'; +import { CustomErrorBase } from '@backstage/errors'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { DocumentDecoratorFactory } from '@backstage/plugin-search-common'; import { DocumentTypeInfo } from '@backstage/plugin-search-common'; @@ -113,6 +114,9 @@ export class LunrSearchEngineIndexer extends BatchSearchEngineIndexer { initialize(): Promise; } +// @public +export class MissingIndexError extends CustomErrorBase {} + // @public export class NewlineDelimitedJsonCollatorFactory implements DocumentCollatorFactory From 34c97eb35ba76c2790f33b3c8616146781c42822 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Wed, 22 Jun 2022 13:39:39 +0200 Subject: [PATCH 05/13] switch to use .json instead of .send Signed-off-by: Emma Indal --- .../src/engines/ElasticSearchSearchEngine.ts | 11 +++++++---- plugins/search-backend-node/api-report.md | 6 ++++-- plugins/search-backend-node/src/errors.ts | 18 ++++++++++++++++-- plugins/search-backend/src/service/router.ts | 8 +------- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts index 8f321a266c..1eb32c882d 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts @@ -362,13 +362,16 @@ export class ElasticSearchSearchEngine implements SearchEngine { nextPageCursor, previousPageCursor, }; - } catch (e) { - if (e.meta.body.error.type === 'index_not_found_exception') { - throw new MissingIndexError(`Missing index for ${queryIndices}`, e); + } catch (error) { + if (error.meta.body.error.type === 'index_not_found_exception') { + throw new MissingIndexError( + `Missing index for ${queryIndices}. This means there are no documents to search through.`, + error, + ); } this.logger.error( `Failed to query documents for indices ${queryIndices}`, - e, + error, ); return Promise.reject({ results: [] }); } diff --git a/plugins/search-backend-node/api-report.md b/plugins/search-backend-node/api-report.md index 63273d7514..ff9480c19d 100644 --- a/plugins/search-backend-node/api-report.md +++ b/plugins/search-backend-node/api-report.md @@ -6,7 +6,6 @@ /// import { Config } from '@backstage/config'; -import { CustomErrorBase } from '@backstage/errors'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { DocumentDecoratorFactory } from '@backstage/plugin-search-common'; import { DocumentTypeInfo } from '@backstage/plugin-search-common'; @@ -115,7 +114,10 @@ export class LunrSearchEngineIndexer extends BatchSearchEngineIndexer { } // @public -export class MissingIndexError extends CustomErrorBase {} +export class MissingIndexError extends Error { + constructor(message?: string, cause?: Error | unknown); + readonly cause?: Error | undefined; +} // @public export class NewlineDelimitedJsonCollatorFactory diff --git a/plugins/search-backend-node/src/errors.ts b/plugins/search-backend-node/src/errors.ts index c6128f3f2e..00b168d460 100644 --- a/plugins/search-backend-node/src/errors.ts +++ b/plugins/search-backend-node/src/errors.ts @@ -14,10 +14,24 @@ * limitations under the License. */ -import { CustomErrorBase } from '@backstage/errors'; +import { isError } from '@backstage/errors'; /** * Failed to query documents for index that does not exist. * @public */ -export class MissingIndexError extends CustomErrorBase {} +export class MissingIndexError extends Error { + /** + * An inner error that caused this error to be thrown, if any. + */ + readonly cause?: Error | undefined; + + constructor(message?: string, cause?: Error | unknown) { + super(message); + + Error.captureStackTrace?.(this, this.constructor); + + this.name = this.constructor.name; + this.cause = isError(cause) ? cause : undefined; + } +} diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index c85b3ed797..0fbacb018e 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -162,13 +162,7 @@ export async function createRouter( res.send(filterResultSet(toSearchResults(resultSet))); } catch (error) { if (error instanceof MissingIndexError) { - res - .status(400) - .send( - `\nNo index found for types: ${ - query.types ? query.types.join(',') : '' - }. This means there are no documents to search through.`, - ); + res.status(400).json(error.message); } throw new Error( From 45e408ce79218b44d94223b953ad04b819b4ecd5 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 28 Jun 2022 11:26:37 +0200 Subject: [PATCH 06/13] feat(search-backend-module-pg): improve error handling Co-authored-by: Emma Indal Signed-off-by: Camila Belo --- .../src/PgSearchEngine/PgSearchEngine.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts index bf98c58de9..d8128f8568 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts @@ -15,6 +15,7 @@ */ import { PluginDatabaseManager } from '@backstage/backend-common'; import { SearchEngine } from '@backstage/plugin-search-backend-node'; +import { MissingIndexError } from '@backstage/plugin-search-backend-node'; import { SearchQuery, IndexableResultSet, @@ -92,6 +93,12 @@ export class PgSearchEngine implements SearchEngine { this.databaseStore.query(tx, pgQuery), ); + if (!rows.length) { + throw new MissingIndexError( + `Missing index for ${pgQuery.types}. This means there are no documents to search through.`, + ); + } + // We requested one result more than the page size to know whether there is // another page. const { page } = decodePageCursor(query.pageCursor); From 8e63e71b2cb02a23c509fbe62b2d4edd6f7ea4d5 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 28 Jun 2022 11:45:10 +0200 Subject: [PATCH 07/13] feat(search-backend-node): improve error handling Co-authored-by: Emma Indal Signed-off-by: Camila Belo --- .../src/engines/LunrSearchEngine.test.ts | 13 +++++ .../src/engines/LunrSearchEngine.ts | 53 +++++++++++-------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts index 098d1e8b16..0bc2e223a6 100644 --- a/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts @@ -949,6 +949,19 @@ describe('LunrSearchEngine', () => { previousPageCursor: undefined, }); }); + + it('should throws missing index error', async () => { + await expect( + async () => + await testLunrSearchEngine.query({ + term: 'testTerm', + types: ['unknown'], + filters: {}, + }), + ).rejects.toThrow( + 'Missing index for unknown. This means there are no documents to search through', + ); + }); }); it('should return previous page cursor if on another page', async () => { diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts index 03cb421653..fcf30f1844 100644 --- a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts @@ -21,6 +21,7 @@ import { QueryTranslator, SearchEngine, } from '@backstage/plugin-search-common'; +import { MissingIndexError } from '../errors'; import lunr from 'lunr'; import { v4 as uuid } from 'uuid'; import { Logger } from 'winston'; @@ -163,30 +164,38 @@ export class LunrSearchEngine implements SearchEngine { const results: LunrResultEnvelope[] = []; + const indexKeys = Object.keys(this.lunrIndices).filter( + type => !documentTypes || documentTypes.includes(type), + ); + + if (!indexKeys.length) { + throw new MissingIndexError( + `Missing index for ${documentTypes?.toString()}. This means there are no documents to search through.`, + ); + } + // Iterate over the filtered list of this.lunrIndex keys. - Object.keys(this.lunrIndices) - .filter(type => !documentTypes || documentTypes.includes(type)) - .forEach(type => { - try { - results.push( - ...this.lunrIndices[type].query(lunrQueryBuilder).map(result => { - return { - result: result, - type: type, - }; - }), - ); - } catch (err) { - // if a field does not exist on a index, we can see that as a no-match - if ( - err instanceof Error && - err.message.startsWith('unrecognised field') - ) { - return; - } - throw err; + indexKeys.forEach(type => { + try { + results.push( + ...this.lunrIndices[type].query(lunrQueryBuilder).map(result => { + return { + result: result, + type: type, + }; + }), + ); + } catch (err) { + // if a field does not exist on a index, we can see that as a no-match + if ( + err instanceof Error && + err.message.startsWith('unrecognised field') + ) { + return; } - }); + throw err; + } + }); // Sort results. results.sort((doc1, doc2) => { From 369a9205957601c7326fd8c26befbf74c0001ced Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 28 Jun 2022 13:16:14 +0200 Subject: [PATCH 08/13] feat(search-backend-module-pg): test error handling Co-authored-by: Emma Indal Signed-off-by: Camila Belo --- .../src/PgSearchEngine/PgSearchEngine.test.ts | 15 +++++++++++++++ .../src/PgSearchEngine/PgSearchEngine.ts | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.test.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.test.ts index 3ed002567e..e106cd6f06 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.test.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.test.ts @@ -271,6 +271,21 @@ describe('PgSearchEngine', () => { limit: 26, }); }); + + it('should throws missing index error', async () => { + database.transaction.mockImplementation(fn => fn(tx)); + database.query.mockResolvedValue([]); + await expect( + async () => + await searchEngine.query({ + term: 'testTerm', + types: ['unknown'], + filters: {}, + }), + ).rejects.toThrow( + 'Missing index for unknown. This means there are no documents to search through', + ); + }); }); }); diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts index d8128f8568..065f25878c 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts @@ -93,7 +93,7 @@ export class PgSearchEngine implements SearchEngine { this.databaseStore.query(tx, pgQuery), ); - if (!rows.length) { + if (pgQuery?.types && !rows.length) { throw new MissingIndexError( `Missing index for ${pgQuery.types}. This means there are no documents to search through.`, ); From 19bcc9d79572de55ffbd2102e7d16536f2f8494f Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 28 Jun 2022 13:46:13 +0200 Subject: [PATCH 09/13] feat(search-backend-module-es): test error handling Co-authored-by: Emma Indal Signed-off-by: Camila Belo --- .../engines/ElasticSearchSearchEngine.test.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.test.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.test.ts index cc88f456b6..d794ea668d 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.test.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.test.ts @@ -793,6 +793,29 @@ describe('ElasticSearchSearchEngine', () => { elasticSearchQuerySpy.mockClear(); }); + + it('should throws missing index error', async () => { + jest.spyOn(clientWrapper, 'search').mockRejectedValue({ + meta: { + body: { + error: { + type: 'index_not_found_exception', + }, + }, + }, + }); + + await expect( + async () => + await testSearchEngine.query({ + term: 'testTerm', + types: ['unknown'], + filters: {}, + }), + ).rejects.toThrow( + 'Missing index for unknown__search. This means there are no documents to search through', + ); + }); }); describe('indexer', () => { From 06f9999f4bca33ac4a2811362cf35e1169b4e6b4 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 28 Jun 2022 13:47:58 +0200 Subject: [PATCH 10/13] feat(search-backend-node): check types in error handling Co-authored-by: Emma Indal Signed-off-by: Camila Belo --- plugins/search-backend-node/src/engines/LunrSearchEngine.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts index fcf30f1844..a06a565d3b 100644 --- a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts @@ -168,7 +168,7 @@ export class LunrSearchEngine implements SearchEngine { type => !documentTypes || documentTypes.includes(type), ); - if (!indexKeys.length) { + if (documentTypes?.length && !indexKeys.length) { throw new MissingIndexError( `Missing index for ${documentTypes?.toString()}. This means there are no documents to search through.`, ); From a21cd4346735a2e1de1a6f104135528733af323a Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Thu, 30 Jun 2022 15:25:28 +0200 Subject: [PATCH 11/13] changesets Signed-off-by: Emma Indal --- .changeset/small-shoes-hide.md | 5 +++++ .changeset/tender-chicken-learn.md | 5 +++++ .changeset/two-owls-cry.md | 6 ++++++ 3 files changed, 16 insertions(+) create mode 100644 .changeset/small-shoes-hide.md create mode 100644 .changeset/tender-chicken-learn.md create mode 100644 .changeset/two-owls-cry.md diff --git a/.changeset/small-shoes-hide.md b/.changeset/small-shoes-hide.md new file mode 100644 index 0000000000..b1f95e9f2d --- /dev/null +++ b/.changeset/small-shoes-hide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-node': patch +--- + +Exports `MissingIndexError` that can be used by the search engines for better error handling when missing index. diff --git a/.changeset/tender-chicken-learn.md b/.changeset/tender-chicken-learn.md new file mode 100644 index 0000000000..bd95c5545f --- /dev/null +++ b/.changeset/tender-chicken-learn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend': patch +--- + +If error is `MissingIndexError` we return a 400 response with a more clear error message. diff --git a/.changeset/two-owls-cry.md b/.changeset/two-owls-cry.md new file mode 100644 index 0000000000..b469561ad7 --- /dev/null +++ b/.changeset/two-owls-cry.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-search-backend-module-elasticsearch': patch +'@backstage/plugin-search-backend-module-pg': patch +--- + +Throws `MissingIndexError` when no index of type exist. From faa5dde25e1dc1b24d85c5a28fadd09a6c1e1614 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Fri, 1 Jul 2022 09:30:47 +0200 Subject: [PATCH 12/13] feedback fixups Signed-off-by: Emma Indal --- .../src/engines/ElasticSearchSearchEngine.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts index eacee57e3f..42c99dfe61 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts @@ -331,7 +331,7 @@ export class ElasticSearchSearchEngine implements SearchEngine { previousPageCursor, }; } catch (error) { - if (error.meta.body.error.type === 'index_not_found_exception') { + if (error.meta?.body?.error?.type === 'index_not_found_exception') { throw new MissingIndexError( `Missing index for ${queryIndices}. This means there are no documents to search through.`, error, From dcba4404597d60d63a267138e36eef2a40750bf7 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 4 Jul 2022 15:52:18 +0200 Subject: [PATCH 13/13] refactor: apply review suggestions Signed-off-by: Camila Belo --- .changeset/two-owls-cry.md | 1 - .../src/engines/ElasticSearchSearchEngine.test.ts | 2 +- .../src/PgSearchEngine/PgSearchEngine.test.ts | 15 --------------- .../src/PgSearchEngine/PgSearchEngine.ts | 7 ------- .../src/engines/LunrSearchEngine.test.ts | 2 +- .../src/engines/LunrSearchEngine.ts | 2 +- plugins/search-backend/src/service/router.ts | 14 ++++++-------- 7 files changed, 9 insertions(+), 34 deletions(-) diff --git a/.changeset/two-owls-cry.md b/.changeset/two-owls-cry.md index b469561ad7..ca371781a1 100644 --- a/.changeset/two-owls-cry.md +++ b/.changeset/two-owls-cry.md @@ -1,6 +1,5 @@ --- '@backstage/plugin-search-backend-module-elasticsearch': patch -'@backstage/plugin-search-backend-module-pg': patch --- Throws `MissingIndexError` when no index of type exist. diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.test.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.test.ts index d794ea668d..b59c67c69c 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.test.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.test.ts @@ -813,7 +813,7 @@ describe('ElasticSearchSearchEngine', () => { filters: {}, }), ).rejects.toThrow( - 'Missing index for unknown__search. This means there are no documents to search through', + 'Missing index for unknown__search. This means there are no documents to search through.', ); }); }); diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.test.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.test.ts index e106cd6f06..3ed002567e 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.test.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.test.ts @@ -271,21 +271,6 @@ describe('PgSearchEngine', () => { limit: 26, }); }); - - it('should throws missing index error', async () => { - database.transaction.mockImplementation(fn => fn(tx)); - database.query.mockResolvedValue([]); - await expect( - async () => - await searchEngine.query({ - term: 'testTerm', - types: ['unknown'], - filters: {}, - }), - ).rejects.toThrow( - 'Missing index for unknown. This means there are no documents to search through', - ); - }); }); }); diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts index 065f25878c..bf98c58de9 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts @@ -15,7 +15,6 @@ */ import { PluginDatabaseManager } from '@backstage/backend-common'; import { SearchEngine } from '@backstage/plugin-search-backend-node'; -import { MissingIndexError } from '@backstage/plugin-search-backend-node'; import { SearchQuery, IndexableResultSet, @@ -93,12 +92,6 @@ export class PgSearchEngine implements SearchEngine { this.databaseStore.query(tx, pgQuery), ); - if (pgQuery?.types && !rows.length) { - throw new MissingIndexError( - `Missing index for ${pgQuery.types}. This means there are no documents to search through.`, - ); - } - // We requested one result more than the page size to know whether there is // another page. const { page } = decodePageCursor(query.pageCursor); diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts index 0bc2e223a6..1f69460448 100644 --- a/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts @@ -959,7 +959,7 @@ describe('LunrSearchEngine', () => { filters: {}, }), ).rejects.toThrow( - 'Missing index for unknown. This means there are no documents to search through', + "Missing index for unknown. This could be because the index hasn't been created yet or there was a problem during index creation.", ); }); }); diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts index a06a565d3b..ec8550d721 100644 --- a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts @@ -170,7 +170,7 @@ export class LunrSearchEngine implements SearchEngine { if (documentTypes?.length && !indexKeys.length) { throw new MissingIndexError( - `Missing index for ${documentTypes?.toString()}. This means there are no documents to search through.`, + `Missing index for ${documentTypes?.toString()}. This could be because the index hasn't been created yet or there was a problem during index creation.`, ); } diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index 0fbacb018e..e4ac233406 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -19,7 +19,7 @@ import Router from 'express-promise-router'; import { Logger } from 'winston'; import { z } from 'zod'; import { errorHandler } from '@backstage/backend-common'; -import { InputError } from '@backstage/errors'; +import { ErrorResponseBody, InputError } from '@backstage/errors'; import { Config } from '@backstage/config'; import { JsonObject, JsonValue } from '@backstage/types'; import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; @@ -33,10 +33,7 @@ import { IndexableResultSet, SearchResultSet, } from '@backstage/plugin-search-common'; -import { - SearchEngine, - MissingIndexError, -} from '@backstage/plugin-search-backend-node'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { AuthorizedSearchEngine } from './AuthorizedSearchEngine'; const jsonObjectSchema: z.ZodSchema = z.lazy(() => { @@ -134,7 +131,7 @@ export async function createRouter( '/query', async ( req: express.Request, - res: express.Response, + res: express.Response, ) => { const parseResult = requestSchema.safeParse(req.query); @@ -161,8 +158,9 @@ export async function createRouter( res.send(filterResultSet(toSearchResults(resultSet))); } catch (error) { - if (error instanceof MissingIndexError) { - res.status(400).json(error.message); + if (error.name === 'MissingIndexError') { + // re-throw and let the default error handler middleware captures it and serializes it with the right response code on the standard form + throw error; } throw new Error(