【问题标题】:Custom error handler in express.js is not called不调用 express.js 中的自定义错误处理程序
【发布时间】:2019-08-28 07:42:29
【问题描述】:

我正在设置一个简单的 express.js 节点服务器,但我似乎无法让我的自定义错误处理程序工作。似乎根本没有调用它,而是调用了一些默认的 express.js 错误处理程序。

请注意,这是在打字稿中,并且使用 mongodb,如果这很重要(不认为它应该)。以下是相关代码:

index.ts:

import routes from './routes/index.ts';
import express, { Request, Response, NextFunction } from 'express';
// other imports...

type ServerErrror = {
    status: number;
    message: string;
}

const app = express();

// set up logging...

app.use(bodyParser.json());
app.use('/', routes);
app.use((err: ServerError, req: Request, res: Response, next: NextFunction) => { // eslint-disable-line no-unused-vars
    console.error('in error handler');
    res.status(err.status).send(`got error: ${err.message}`);
});

mongoose.connect(MONGODB_URI)
    .then(() => {
        console.log('Successfully connected to database.');
        app.listen(SERVER_PORT, () => {
            console.log(`Server is up and running on port ${SERVER_PORT}`);
        }).on('error', error => {
            console.log('Error starting server:', error);
        });
    }, error => {
        console.log('Error connecting to database:', error);
    });

路由/index.ts:

import { Router } from 'express';
import dataRoutes from './data.ts';

const router = Router();

router.use('/data', dataRoutes);

export default router;

路由/data.ts:

import { Router } from 'express';
import Data from './models/Data';

const router = Router();

router.get('/', (_, res, next) => {
    Data.find((error, data) => {
        if (error) {
            console.log('found an error')
            next({ status: 500, message: 'got an error' });
            return;
        }
        res.send(`Got data: ${JSON.stringify(data.map(datum => datum.toJSON()))}`);
    });
});

export default router;

当我启动服务器然后使用 postman 向 /data 端点发送 GET 请求时,这是服务器上的输出:

Successfully connected to database.
Server is up and running on port 1234
found an error
GET /data 500 35.289 ms - 142 // this is from morgan logging
[object Object] // no idea where this is coming from, i assume express default error handler

这是我在邮递员中看到的返回值:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Error</title>
    </head>
    <body>
        <pre>[object Object]</pre>
    </body>
</html>

再次,不确定这是从哪里来的。我认为它必须是明确的默认错误处理程序。

【问题讨论】:

  • 你能在你的错误处理程序中console.log(err) 看看结构
  • @naga-elixir-jar 我已经有一个console.error 并且它没有被调用,因为它没有到达那里

标签: javascript node.js typescript express error-handling


【解决方案1】:

就我而言,我禁用了 babel-preset-minify 选项 deadcode 并且运行良好。

{
  "presets": [
    [
      "minify",
      {
        "deadcode": false
      }
    ]
  ]
}

【讨论】:

    【解决方案2】:

    原来问题是我使用了babel-preset-minify,它显然没有正确转换代码。去掉这个预设后,代码无需其他修改即可工作。

    【讨论】:

      【解决方案3】:

      你的代码有一些问题:

      • import routes from './routes/index.ts' 不应具有 *.ts 扩展名。
      • import dataRoutes from './data.ts'; 不应具有 *.ts 扩展名。
      • ServerErrror 有一个太多的字母。

      这是在我的机器上工作的简短示例。我删除了与 Mongoose 相关的代码并更改了示例,以便在单个文件中轻松重现。对http://localhost:5000/data 的调用返回customErrorHandler &gt; dataRoutes.get &gt; Error,我认为这是您需要的。

      import { Request, Response, NextFunction } from 'express';
      import bodyParser = require('body-parser');
      import express = require('express');
      
      type ServerError = {
        status: number;
        message: string;
      }
      
      const dataRoutes = express.Router().get('/', (_, res, next) => {
        setTimeout(() => { // mimic an asynchronous operation
          const error = true;
          if (error) {
            next({ status: 500, message: 'dataRoutes.get > Error' });
            return;
          }
      
          res.send('dataRoutes.get > Success');
        }, 1000);
      });
      
      const routes = express.Router().use('/data', dataRoutes);
      
      const app = express();
      app.use(bodyParser.json());
      app.use('/', routes);
      app.use((err: ServerError, req: Request, res: Response, next: NextFunction) => {
        res
          .status(err.status)
          .send(`customErrorHandler > ${err.message}`);
      });
      
      app.listen(5000);
      console.log('Now listening on port 5000');
      

      这是我的 tsconfig.json 文件:

      {
        "compilerOptions": {
          "moduleResolution": "node",
          "module": "commonjs",
          "allowSyntheticDefaultImports": true
        }
      }
      

      这些是我的 package.json 依赖项:

      "devDependencies": {
        "@types/express": "^4.16.1",
        "typescript": "^3.4.1"
      },
      "dependencies": {
        "express": "^4.16.4"
      }
      

      【讨论】:

      • 我复制粘贴了这段代码并运行了它,当我到达端点时它仍然没有调用自定义错误处理程序。请问你用的是什么版本的快递? (和身体解析器,为什么不)
      • 当然。我添加了可能感兴趣的 package.json 和 tsconfig.json 部分。
      • 所以,经过大量挖掘,我发现了问题所在。我会为它创建一个单独的答案,因为你的帖子没有给我答案。但是,我赞成您的帖子/评论,因为它有助于在调试过程中指导我。
      • 为了后代:您在帖子顶部指出的错误仅存在于我的帖子中,因为我试图编辑我的实际代码以使代码更简单地用于 stackoverflow。它们不是我必须纠正的实际错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-18
      • 2011-10-02
      • 2018-04-29
      • 2011-06-01
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      相关资源
      最近更新 更多