From 82af0855bc2d9fe8ae71d2d84af9dd467f51507a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 8 Feb 2021 12:21:47 +0100 Subject: [PATCH 1/3] backend-common: use explicit content type in error response --- packages/backend-common/src/middleware/errorHandler.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/backend-common/src/middleware/errorHandler.ts b/packages/backend-common/src/middleware/errorHandler.ts index a08849813d..2f3b904d38 100644 --- a/packages/backend-common/src/middleware/errorHandler.ts +++ b/packages/backend-common/src/middleware/errorHandler.ts @@ -63,10 +63,10 @@ export function errorHandler( return ( error: Error, _request: Request, - response: Response, + res: Response, next: NextFunction, ) => { - if (response.headersSent) { + if (res.headersSent) { // If the headers have already been sent, do not send the response again // as this will throw an error in the backend. next(error); @@ -80,7 +80,9 @@ export function errorHandler( logger.error(error); } - response.status(status).send(message); + res.status(status); + res.setHeader('content-type', 'text/plain'); + res.send(message); }; } From 3c4444cea2b0f65c8676d2829cf059edf7db9b46 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 8 Feb 2021 13:20:45 +0100 Subject: [PATCH 2/3] catalog-backend: use more explicit response types and let error handlers handle errors --- plugins/catalog-backend/src/service/router.ts | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/plugins/catalog-backend/src/service/router.ts b/plugins/catalog-backend/src/service/router.ts index 6064164e31..17cfc77d8b 100644 --- a/plugins/catalog-backend/src/service/router.ts +++ b/plugins/catalog-backend/src/service/router.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { errorHandler } from '@backstage/backend-common'; +import { errorHandler, NotFoundError } from '@backstage/backend-common'; import { locationSpecSchema, analyzeLocationSchema, @@ -57,7 +57,7 @@ export async function createRouter( const filter = EntityFilters.ofQuery(req.query); const fieldMapper = translateQueryToFieldMapper(req.query); const entities = await entitiesCatalog.entities(filter); - res.status(200).send(entities.map(fieldMapper)); + res.status(200).json(entities.map(fieldMapper)); }) .post('/entities', async (req, res) => { const body = await requireRequestBody(req); @@ -67,7 +67,7 @@ export async function createRouter( const [entity] = await entitiesCatalog.entities( EntityFilters.ofMatchers({ 'metadata.uid': result.entityId }), ); - res.status(200).send(entity); + res.status(200).json(entity); }) .get('/entities/by-uid/:uid', async (req, res) => { const { uid } = req.params; @@ -75,15 +75,14 @@ export async function createRouter( EntityFilters.ofMatchers({ 'metadata.uid': uid }), ); if (!entities.length) { - res.status(404).send(`No entity with uid ${uid}`); - } else { - res.status(200).send(entities[0]); + throw new NotFoundError(`No entity with uid ${uid}`); } + res.status(200).json(entities[0]); }) .delete('/entities/by-uid/:uid', async (req, res) => { const { uid } = req.params; await entitiesCatalog.removeEntityByUid(uid); - res.status(204).send(); + res.status(204).end(); }) .get('/entities/by-name/:kind/:namespace/:name', async (req, res) => { const { kind, namespace, name } = req.params; @@ -95,14 +94,11 @@ export async function createRouter( }), ); if (!entities.length) { - res - .status(404) - .send( - `No entity with kind ${kind} namespace ${namespace} name ${name}`, - ); - } else { - res.status(200).send(entities[0]); + throw new NotFoundError( + `No entity with kind ${kind} namespace ${namespace} name ${name}`, + ); } + res.status(200).json(entities[0]); }); } @@ -111,7 +107,7 @@ export async function createRouter( const input = await validateRequestBody(req, locationSpecSchema); const dryRun = yn(req.query.dryRun, { default: false }); const output = await higherOrderOperation.addLocation(input, { dryRun }); - res.status(201).send(output); + res.status(201).json(output); }); } @@ -119,22 +115,22 @@ export async function createRouter( router .get('/locations', async (_req, res) => { const output = await locationsCatalog.locations(); - res.status(200).send(output); + res.status(200).json(output); }) .get('/locations/:id/history', async (req, res) => { const { id } = req.params; const output = await locationsCatalog.locationHistory(id); - res.status(200).send(output); + res.status(200).json(output); }) .get('/locations/:id', async (req, res) => { const { id } = req.params; const output = await locationsCatalog.location(id); - res.status(200).send(output); + res.status(200).json(output); }) .delete('/locations/:id', async (req, res) => { const { id } = req.params; await locationsCatalog.removeLocation(id); - res.status(204).send(); + res.status(204).end(); }); } @@ -142,7 +138,7 @@ export async function createRouter( router.post('/analyze-location', async (req, res) => { const input = await validateRequestBody(req, analyzeLocationSchema); const output = await locationAnalyzer.analyzeLocation(input); - res.status(200).send(output); + res.status(200).json(output); }); } From 82b2c11b67472ec8ba2f44219e04151aadf5cc24 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 8 Feb 2021 13:26:11 +0100 Subject: [PATCH 3/3] added changesets --- .changeset/odd-buckets-compare.md | 5 +++++ .changeset/strange-cobras-unite.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/odd-buckets-compare.md create mode 100644 .changeset/strange-cobras-unite.md diff --git a/.changeset/odd-buckets-compare.md b/.changeset/odd-buckets-compare.md new file mode 100644 index 0000000000..faf68fb4a0 --- /dev/null +++ b/.changeset/odd-buckets-compare.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Set explicit content-type in error handler responses. diff --git a/.changeset/strange-cobras-unite.md b/.changeset/strange-cobras-unite.md new file mode 100644 index 0000000000..d53a324dab --- /dev/null +++ b/.changeset/strange-cobras-unite.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Refactored route response handling to use more explicit types and throw errors.