From c2cf80c72a9884e02c67754211d4ec367075078e Mon Sep 17 00:00:00 2001 From: Alberto Casado Torres Date: Mon, 25 Oct 2021 12:33:34 +0200 Subject: [PATCH] General error handling for express routes --- app/api/search.v2/routes.ts | 14 ++------------ app/api/search.v2/specs/routes.spec.ts | 1 + app/api/utils/routesErrorHandler.ts | 26 ++++++++++++++++++++++++++ app/api/utils/testingRoutes.ts | 2 ++ app/server.js | 3 +++ 5 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 app/api/utils/routesErrorHandler.ts diff --git a/app/api/search.v2/routes.ts b/app/api/search.v2/routes.ts index a6168fcbbf9..cda9675b6ca 100644 --- a/app/api/search.v2/routes.ts +++ b/app/api/search.v2/routes.ts @@ -24,16 +24,6 @@ interface UwaziReq extends Request { type UwaziRes = Omit & { json(data: UwaziResponse): Response }; -const captureError = ( - callback: (req: Request, res: Response, next: NextFunction) => Promise -) => async (req: Request, res: Response, next: NextFunction) => { - try { - await callback(req, res, next); - } catch (e) { - next(e); - } -}; - const searchRoutes = (app: Application) => { app.get( '/api/v2/entities', @@ -43,7 +33,7 @@ const searchRoutes = (app: Application) => { query: SearchQuerySchema, }, }), - captureError(async (req: UwaziReq, res: UwaziRes) => { + async (req: UwaziReq, res: UwaziRes) => { const { query, language, url } = req; const response = await elastic.search({ body: await buildQuery(query, language) }); @@ -55,7 +45,7 @@ const searchRoutes = (app: Application) => { first: query.page?.limit ? url : undefined, }, }); - }) + } ); }; diff --git a/app/api/search.v2/specs/routes.spec.ts b/app/api/search.v2/specs/routes.spec.ts index 39306bf5158..dd49dd91ca7 100644 --- a/app/api/search.v2/specs/routes.spec.ts +++ b/app/api/search.v2/specs/routes.spec.ts @@ -6,6 +6,7 @@ import { elastic } from 'api/search'; import { testingEnvironment } from 'api/utils/testingEnvironment'; import { searchRoutes } from '../routes'; + import { fixturesTitleSearch, entity1en, diff --git a/app/api/utils/routesErrorHandler.ts b/app/api/utils/routesErrorHandler.ts new file mode 100644 index 00000000000..df16183b06f --- /dev/null +++ b/app/api/utils/routesErrorHandler.ts @@ -0,0 +1,26 @@ +/* eslint-disable no-param-reassign */ +import { Application } from 'express'; + +const wrapHandler = (originalHandler: any) => async (req: any, res: any, next: any) => { + try { + await originalHandler(req, res, next); + } catch (err) { + next(err); + } +}; + +const routesErrorHandler = (app: Application) => { + const originalGet = app.get.bind(app); + app.get = (path: any, ...args: any[]) => originalGet(path, ...args.map(wrapHandler)); + + const originalPost = app.post.bind(app); + app.post = (path: any, ...args: any[]) => originalPost(path, ...args.map(wrapHandler)); + + const originalDelete = app.delete.bind(app); + app.delete = (path: any, ...args: any[]) => originalDelete(path, ...args.map(wrapHandler)); + + const originalPut = app.put.bind(app); + app.put = (path: any, ...args: any[]) => originalPut(path, ...args.map(wrapHandler)); +}; + +export { routesErrorHandler }; diff --git a/app/api/utils/testingRoutes.ts b/app/api/utils/testingRoutes.ts index 2907007e354..0e5eb821831 100644 --- a/app/api/utils/testingRoutes.ts +++ b/app/api/utils/testingRoutes.ts @@ -4,6 +4,7 @@ import { Response as SuperTestResponse } from 'supertest'; import errorHandlingMiddleware from 'api/utils/error_handling_middleware'; import languageMiddleware from 'api/utils/languageMiddleware'; +import { routesErrorHandler } from 'api/utils/routesErrorHandler'; import { extendSupertest } from './supertestExtensions'; extendSupertest(); @@ -15,6 +16,7 @@ const setUpApp = ( ...customMiddleware: ((req: Request, _es: Response, next: NextFunction) => void)[] ): Application => { const app: Application = express(); + routesErrorHandler(app); app.use(bodyParser.json()); app.use((req: Request, _res: Response, next: NextFunction) => { req.emitToSessionSocket = (event: string, ...args: any[]) => iosocket.emit(event, ...args); diff --git a/app/server.js b/app/server.js index e1364c4c6a1..8b35e7cf5e7 100644 --- a/app/server.js +++ b/app/server.js @@ -3,6 +3,7 @@ import bodyParser from 'body-parser'; import compression from 'compression'; import express from 'express'; + import helmet from 'helmet'; import { Server } from 'http'; import mongoose from 'mongoose'; @@ -33,10 +34,12 @@ import { staticFilesMiddleware } from './api/utils/staticFilesMiddleware'; import { customUploadsPath, uploadsPath } from './api/files/filesystem'; import { tocService } from './api/toc_generation/tocService'; import { permissionsContext } from './api/permissions/permissionsContext'; +import { routesErrorHandler } from './api/utils/routesErrorHandler'; mongoose.Promise = Promise; const app = express(); +routesErrorHandler(app); app.use(helmet()); const http = Server(app);