简体   繁体   中英

Handling Errors in Express Class with Typescript

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> &nbsp; &nbsp;at /Users/nrb/Development/Borduhh/SaasyNode/server/dist/app.js: 39: 25<br> &nbsp; &nbsp;at Layer.handle [as handle_request
] (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/layer.js: 95: 5)<br> &nbsp; &nbsp;at trim_prefix (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/index.js: 317: 13)<br> &nbsp; &nbsp;at /Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/index.js: 284: 7<br> &nbsp; &nbsp;at Function.process_params (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/index.js: 335: 12)<br> &nbsp; &nbsp;at next (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/express/lib/router/index.js: 275: 10)<br> &nbsp; &nbsp;at /Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/body-parser/lib/read.js: 130: 5<br> &nbsp; &nbsp;at invokeCallback (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/raw-body/index.js: 224: 16)<br> &nbsp; &nbsp;at done (/Users/nrb/Development/Borduhh/SaasyNode/server/node_modules/raw-body/index.js: 213: 7)<br> &nbsp; &nbsp;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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM