Handle 404 in Express servers
MODIFY
src/server/ExpressUtils.ts
src/server/ExpressUtils.ts
-import express, { NextFunction, Request, Response } from 'express';
+import express, { Application, NextFunction, Request, Response } from 'express';
import Configuration from '../utils/Configuration';
import Constants from '../utils/Constants';
@@ -17,7 +17,7 @@ import useragent from 'express-useragent';
bodyParserXml(bodyParser);
export default class ExpressUtils {
- public static initApplication(bodyLimit = '1mb', debug = false): express.Application {
+ public static initApplication(bodyLimit = '1mb', debug = false): Application {
const app = express();
// Secure the application
app.use(helmet());

MODIFY
src/server/ocpi/AbstractOCPIService.ts
src/server/ocpi/AbstractOCPIService.ts
@@ -28,28 +28,20 @@ export default abstract class AbstractOCPIService {
private endpoints: Map<string, AbstractEndpoint> = new Map<string, AbstractEndpoint>();
- // Create OCPI Service
protected constructor(
private readonly ocpiRestConfig: OCPIServiceConfiguration,
private readonly role: string,
private readonly version: string) {
}
- /**
- * Register Endpoint to this service
- *
- * @param {AbstractEndpoint} endpoint
- */
public registerEndpoint(endpoint: AbstractEndpoint): void {
this.endpoints.set(endpoint.getIdentifier(), endpoint);
}
- // Get All Registered Endpoint
public getRegisteredEndpoints(): Map<string, AbstractEndpoint> {
return this.endpoints;
}
- // Return based URL of OCPI Service
public getServiceUrl(req: Request): string {
const baseUrl = this.getBaseUrl(req);
const path = this.getPath();
@@ -57,7 +49,6 @@ export default abstract class AbstractOCPIService {
return `${baseUrl}${path}`;
}
- // Get BaseUrl ${protocol}://${host}
public getBaseUrl(req: Request): string {
const protocol = (this.ocpiRestConfig.externalProtocol ? this.ocpiRestConfig.externalProtocol : 'https');
// Get host from the req
@@ -66,7 +57,6 @@ export default abstract class AbstractOCPIService {
return `${protocol}://${host}`;
}
- // Get Relative path of the service
public getPath(): string {
return `${this.role}/${this.version}/`;
}
@@ -75,7 +65,6 @@ export default abstract class AbstractOCPIService {
return this.version;
}
- // Rest Service Implementation
public async restService(req: TenantIdHoldingRequest, res: Response, next: NextFunction): Promise<void> {
// Parse the action
// FIXME: use a express request parameter instead of using regexp to parse the request URL

MODIFY
src/server/ocpi/OCPIServer.ts
src/server/ocpi/OCPIServer.ts
@@ -46,6 +46,15 @@ export default class OCPIServer {
}
});
}
+ // Not found
+ this.expressApplication.use((req: Request, res: Response, next: NextFunction) => {
+ res.status(404);
+ res.format({
+ html: () => res.send(`404: ${req.url}`),
+ json: () => res.json({ error: `404: ${req.url}` }),
+ default: () => res.type('txt').send(`404: ${req.url}`)
+ });
+ });
// Post init
ExpressUtils.postInitApplication(this.expressApplication);
}

MODIFY
src/server/odata/ODataServer.ts
src/server/odata/ODataServer.ts
-import express, { NextFunction, Request, Response } from 'express';
+import { Application, NextFunction, Request, Response } from 'express';
import Configuration from '../../utils/Configuration';
import ExpressUtils from '../ExpressUtils';
@@ -14,7 +14,7 @@ const MODULE_NAME = 'ODataServer';
export default class ODataServer {
private oDataServerConfig: ODataServiceConfiguration;
- private expressApplication: express.Application;
+ private expressApplication: Application;
// Create the rest server
constructor(oDataServerConfig: ODataServiceConfiguration) {
@@ -44,6 +44,15 @@ export default class ODataServer {
}
}
);
+ // Not found
+ this.expressApplication.use((req: Request, res: Response, next: NextFunction) => {
+ res.status(404);
+ res.format({
+ html: () => res.send(`404: ${req.url}`),
+ json: () => res.json({ error: `404: ${req.url}` }),
+ default: () => res.type('txt').send(`404: ${req.url}`)
+ });
+ });
// Post init
ExpressUtils.postInitApplication(this.expressApplication);
}

MODIFY
src/server/oicp/OICPServer.ts
src/server/oicp/OICPServer.ts
-import { Application, NextFunction, Response } from 'express';
+import { Application, NextFunction, Request, Response } from 'express';
import ExpressUtils from '../ExpressUtils';
import Logging from '../../utils/Logging';
@@ -34,6 +34,15 @@ export default class OICPServer {
}
});
});
+ // Not found
+ this.expressApplication.use((req: Request, res: Response, next: NextFunction) => {
+ res.status(404);
+ res.format({
+ html: () => res.send(`404: ${req.url}`),
+ json: () => res.json({ error: `404: ${req.url}` }),
+ default: () => res.type('txt').send(`404: ${req.url}`)
+ });
+ });
// Post init
ExpressUtils.postInitApplication(this.expressApplication);
}

MODIFY
src/server/rest/CentralRestServer.ts
src/server/rest/CentralRestServer.ts
+import { Application, NextFunction, Request, Response } from 'express';
+
import AuthService from './v1/service/AuthService';
import CentralRestServerService from './CentralRestServerService';
import CentralSystemRestServiceConfiguration from '../../types/configuration/CentralSystemRestServiceConfiguration';
@@ -6,7 +8,6 @@ import GlobalRouter from './v1/router/GlobalRouter';
import Logging from '../../utils/Logging';
import { ServerType } from '../../types/Server';
import { ServerUtils } from '../ServerUtils';
-import express from 'express';
import http from 'http';
import sanitize from 'express-sanitizer';
@@ -15,7 +16,7 @@ const MODULE_NAME = 'CentralRestServer';
export default class CentralRestServer {
private static centralSystemRestConfig: CentralSystemRestServiceConfiguration;
private static restHttpServer: http.Server;
- private expressApplication: express.Application;
+ private expressApplication: Application;
// Create the rest server
constructor(centralSystemRestConfig: CentralSystemRestServiceConfiguration) {
@@ -37,16 +38,15 @@ export default class CentralRestServer {
this.expressApplication.use('/client/util/:action',
Logging.traceExpressRequest.bind(this),
CentralRestServerService.restServiceUtil.bind(this));
- // Unknwon Route
- // TODO: Called before other routes: To Check
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
- // this.expressApplication.use((req: Request, res: Response, next: NextFunction) => {
- // if (!res.headersSent) {
- // console.log(`Res status: ${res.statusCode}, url: ${req.url}`);
- // res.sendStatus(StatusCodes.NOT_FOUND);
- // }
- // next();
- // });
+ // Not found
+ this.expressApplication.use((req: Request, res: Response, next: NextFunction) => {
+ res.status(404);
+ res.format({
+ html: () => res.send(`404: ${req.url}`),
+ json: () => res.json({ error: `404: ${req.url}` }),
+ default: () => res.type('txt').send(`404: ${req.url}`)
+ });
+ });
// Post init
ExpressUtils.postInitApplication(this.expressApplication);
// Create HTTP server to serve the express app

Handle 404 in Express servers