【问题标题】:Return JSON from Express error handling middleware instead of HTML从 Express 错误处理中间件返回 JSON 而不是 HTML
【发布时间】:2019-07-16 15:15:01
【问题描述】:

我在从我的 Express 处理中间件返回 JSON 响应时遇到了一点问题。目前,我在 Postman 中收到一个 HTML 错误页面。在我的实际客户端上,我只从控制台中的fetch 请求返回一个500 error。应该是错误消息的 JSON 数据没有按预期通过。

这是我的错误处理函数。它只是将错误作为 JSON 响应传递回客户端。任何时候在我的控制器路由中调用next(some_error),Express 都会通过这个错误处理函数对它们进行管道传输:

const express = require('express');
const router = express.Router();

exports.errorHandler = (err, req, res, next) => {
  res.setHeader('Content-type', 'application/json');
  res.status(500).json({ err });
};

module.exports = router;

这是控制器路由的一部分,我故意在其中抛出一个错误以测试错误处理中间件:

   if (isMatch) {
      const payload = { id: user._id };

      jwt.sign(
        payload,
        JWT_SECRET_KEY,
        { expiresIn: 900000 },
        (err, token) => {
          if (err) {
            const error = new Error(JWT_FAILED);
            error.httpStatusCode = 400;
            return next(error);
          }
          payload.token = `Bearer ${token}`;
          return res.status(200).json({
            success: true,
            accountant: payload
          });
        }
      );
    } else {
      const error = new Error(PASSWORD_INCORRECT);
      error.genericError =
        'The provided password did not match the database.';
      error.httpStatusCode = 400;
      return next(error);
    }

这是我收到的回复以供参考的页面:

我不确定我做错了什么,我通常不会遇到从 Express 发回 JSON 响应的问题。我有一种预感,Express 处理的错误需要一个额外的步骤才能默认返回为 HTML 而不是 JSON。

【问题讨论】:

  • 您的errorHandler 实际附加到app 的位置在哪里?
  • 在我的server.js 中的路线下方:看起来像:app.use(errorHandler);。最初我应该提到这一点,但我的错误处理程序正在工作(尽管没有返回 JSON),所以我没有考虑包含它。
  • 需要注意的是,您的res.setHeader() 调用是多余的。 res.json() 方法已经在响应中设置了正确的 Content-Type。在您的errorHandler 之前,您还有其他错误处理中间件吗?我还会在你的errorHandler 中添加一个console.log(),最好插入一个Date,这样你就可以准确地看到它何时(或何时不)被调用。
  • @PatrickRoberts 我确实有另一个错误处理中间件,用于在我的终端中注销错误的端点请求。我已经对此发表了评论,以查看这是否导致问题并且没有任何影响。我徒劳地使用了res.setHeader(),试图让它工作,删除它并离开res.json(),但仍然返回一个HTML页面。
  • 那么,鉴于此信息,我没有想法,但我建议将console.log() 添加到您管道中的每个相关区域,以验证您到目前为止所做的假设。我遇到了几个我无法修复的错误,直到我意识到我对代码所做的一些隐含假设是错误的。

标签: javascript node.js express ecmascript-6


【解决方案1】:

这解决了我的问题。我删除了router 并添加了module.exports = errorHandler,这解决了这个问题。 Express 没有调用我的 errorHandler 中间件函数。它只是在我的控制器路由中看到next(some_error),然后以默认方式返回错误。我以为我的 errorHandler 函数正在返回这个,而事实上,我的函数甚至从未被调用过。

这是更新的错误处理中间件:

const errorHandler = (err, req, res, next) => {
  res.json({ err: 'and error' });
};

module.exports = errorHandler;

现在这会发回 JSON。呸呸呸。

【讨论】:

  • 因此,这与 JSON、表达、错误处理或您的标题/问题所暗示的任何内容都无关。这一切都是为了了解require() 的工作原理。这使得这个问答成为重复的,如果不进行大量编辑,它就毫无用处。我会删除这个答案,然后是问题,tbh。
  • 他们说事后看来是 20/20,但我不敢相信我忽略了这一点。很好的发现。
  • @ChrisG 当然,将其标记为重复。这不需要删除问题或答案。如果他们愿意,他们可以自行决定这样做。重复的问题可以仍然有助于网站,这是一个很好的问题和答案的好例子。 OP 对反馈做出响应,提供了足够的信息来重现问题等。老实说,我不明白仅仅因为之前已经解决了同样的问题就必须删除问题的心态......
  • @ChrisG 如果我能在真正知道问题所在时写下标题就好了。其他人可能会犯同样的错误,因为在定义导出的错误处理中间件函数时,Express 文档的解释很枯燥。我以为我需要用router 导出错误处理中间件函数,但事实并非如此。
  • @maison.m 抱歉,我无意以任何方式粗鲁。当然,当您发布此内容时,您并没有意识到实际问题是什么;我并不是说这是你的错或类似的事情(尽管解释节点模块的工作方式不是快速文档的工作)。我要说的是,这个问题应该根据实际问题进行编辑。
猜你喜欢
  • 2018-03-03
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 2022-01-01
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多