Change the response status of metadata endpoints in case a documentation is not available to 404 NOT FOUND
Signed-off-by: Oliver Sand <oliver.sand@sda-se.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
---
|
||||
|
||||
Change the response status of metadata endpoints in case a documentation is not
|
||||
available to `404 NOT FOUND`. This also introduces the JSON based error messages
|
||||
used by other backends.
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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 { getEntityNameFromUrlPath } from './helpers';
|
||||
|
||||
describe('getEntityNameFromUrlPath', () => {
|
||||
it('should parse correctly', () => {
|
||||
const path = 'default/Component/documented-component';
|
||||
const parsedEntity = getEntityNameFromUrlPath(path);
|
||||
expect(parsedEntity).toHaveProperty('namespace', 'default');
|
||||
expect(parsedEntity).toHaveProperty('kind', 'Component');
|
||||
expect(parsedEntity).toHaveProperty('name', 'documented-component');
|
||||
});
|
||||
});
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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 { EntityName } from '@backstage/catalog-model';
|
||||
/**
|
||||
* Using the path of the TechDocs page URL, return a structured EntityName type object with namespace,
|
||||
* kind and name of the Entity.
|
||||
* @param {string} path Example: default/Component/documented-component
|
||||
*/
|
||||
export const getEntityNameFromUrlPath = (path: string): EntityName => {
|
||||
const [namespace, kind, name] = path.split('/');
|
||||
|
||||
return {
|
||||
namespace,
|
||||
kind,
|
||||
name,
|
||||
};
|
||||
};
|
||||
@@ -14,8 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { NotFoundError } from '@backstage/errors';
|
||||
import {
|
||||
GeneratorBuilder,
|
||||
getLocationForEntity,
|
||||
@@ -30,8 +31,6 @@ import { Knex } from 'knex';
|
||||
import { Logger } from 'winston';
|
||||
import { DocsBuilder } from '../DocsBuilder';
|
||||
import { shouldCheckForUpdate } from '../DocsBuilder/BuildMetadataStorage';
|
||||
import { getEntityNameFromUrlPath } from './helpers';
|
||||
import { NotFoundError } from '@backstage/errors';
|
||||
|
||||
type RouterOptions = {
|
||||
preparers: PreparerBuilder;
|
||||
@@ -55,10 +54,9 @@ export async function createRouter({
|
||||
}: RouterOptions): Promise<express.Router> {
|
||||
const router = Router();
|
||||
|
||||
router.get('/metadata/techdocs/*', async (req, res) => {
|
||||
// path is `:namespace/:kind:/:name`
|
||||
const { '0': path } = req.params;
|
||||
const entityName = getEntityNameFromUrlPath(path);
|
||||
router.get('/metadata/techdocs/:namespace/:kind/:name', async (req, res) => {
|
||||
const { kind, namespace, name } = req.params;
|
||||
const entityName = { kind, namespace, name };
|
||||
|
||||
try {
|
||||
const techdocsMetadata = await publisher.fetchTechDocsMetadata(
|
||||
@@ -67,14 +65,15 @@ export async function createRouter({
|
||||
|
||||
res.json(techdocsMetadata);
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
`Unable to get metadata for ${entityName.namespace}/${entityName.name} with error ${err}`,
|
||||
logger.info(
|
||||
`Unable to get metadata for '${stringifyEntityRef(
|
||||
entityName,
|
||||
)}' with error ${err}`,
|
||||
);
|
||||
throw new NotFoundError(
|
||||
`Unable to get metadata for '${stringifyEntityRef(entityName)}'`,
|
||||
err,
|
||||
);
|
||||
res
|
||||
.status(500)
|
||||
.send(
|
||||
`Unable to get metadata for $${entityName.namespace}/${entityName.name}, reason: ${err}`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -82,9 +81,11 @@ export async function createRouter({
|
||||
const catalogUrl = await discovery.getBaseUrl('catalog');
|
||||
|
||||
const { kind, namespace, name } = req.params;
|
||||
const entityName = { kind, namespace, name };
|
||||
|
||||
try {
|
||||
const token = getBearerToken(req.headers.authorization);
|
||||
// TODO: Consider using the catalog client here
|
||||
const entity = (await (
|
||||
await fetch(
|
||||
`${catalogUrl}/entities/by-name/${kind}/${namespace}/${name}`,
|
||||
@@ -98,10 +99,13 @@ export async function createRouter({
|
||||
res.json({ ...entity, locationMetadata });
|
||||
} catch (err) {
|
||||
logger.info(
|
||||
`Unable to get metadata for ${kind}/${namespace}/${name} with error ${err}`,
|
||||
`Unable to get metadata for '${stringifyEntityRef(
|
||||
entityName,
|
||||
)}' with error ${err}`,
|
||||
);
|
||||
throw new Error(
|
||||
`Unable to get metadata for ${kind}/${namespace}/${name} with error ${err}`,
|
||||
throw new NotFoundError(
|
||||
`Unable to get metadata for '${stringifyEntityRef(entityName)}'`,
|
||||
err,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user