I am re-writing my Express.js application as a Typescript class and having some trouble with handling errors. Here is my App.ts
class file:
import express from 'express';
import compression from 'compression';
import logger from './util/logger';
/**
* Express Application Class
*/
class App {
public app: express.Application;
public port: number;
constructor(port = 3000) {
this.app = express();
this.port = port;
this.registerMiddleware();
// this.registerRoutes();
this.routeNotFoundHandler();
this.errorHandler();
}
/**
* Registers middleware for use
*/
private registerMiddleware(): void {
this.app.use(compression());
this.app.use(express.json());
this.app.use(express.urlencoded({ extended: false }));
}
// /**
// * Registers routes for use
// */
// private registerRoutes(): void {}
/**
* Registers 404 Route
*/
private routeNotFoundHandler(): void {
this.app.use(
(req: express.Request, res: express.Response, next: express.NextFunction): void => {
res.status(404);
return next(new Error('Bad Request'));
}
);
}
/**
* Registers Error Handler
*/
private errorHandler(): void {
this.app.use((err: Error, req: express.Request, res: express.Response) => {
return res.json({
status: 'error',
error: err.message,
data: [],
});
});
}
/**
* Starts the Express.js server.
*/
public listen(): void {
this.app.listen(this.port, () => {
logger.info(`Express application started.`);
});
}
}
export default App;
When I navigate to a URL that is not registered (ie http://localhost:3000/users
), I expect the App class to trigger the routeNotFoundHandler()
method which then sets the status to 404 and passes the error to the errorHandler()
method:
res.status(404);
return next(new Error('Bad Request'));
There errorHandler()
should then return a JSON response with the error message:
return res.json({
status: 'error',
error: err.message,
data: [],
});
However, for some reason when I visit that test URL in Postman, I am getting the response as HTML from Express:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Error: Bad Request<br> at /Users/nrb/Development/Borduhh/SaasyNode/server/dist/app.js: 39: 25<br> at Layer.handle [as handle_request
] (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/layer.js: 95: 5)<br> at trim_prefix (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/index.js: 317: 13)<br> at /Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/index.js: 284: 7<br> at Function.process_params (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/index.js: 335: 12)<br> at next (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/index.js: 275: 10)<br> at /Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/body-parser/lib/read.js: 130: 5<br> at invokeCallback (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/raw-body/index.js: 224: 16)<br> at done (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/raw-body/index.js: 213: 7)<br> at IncomingMessage.onEnd (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/raw-body/index.js: 273: 7)</pre>
</body>
</html>
try to replace your error handler with the following:
/**
* Registers Error Handler
*/
private errorHandler(): void {
this.app.use((err: Error, req: express.Request, res: express.Response, _next: express.NextFunction) => {
return res.json({
status: 'error',
error: err.message,
data: [],
});
});
}
I've also encountered into this deceptive API behavior, it seems like Express recognizes error handlers only if you pass the 4th argument, even is it's not used:-/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.