【问题标题】:Error handler ignored when NODE_ENV=production当 NODE_ENV=production 时忽略错误处理程序
【发布时间】:2019-01-18 19:17:07
【问题描述】:

我正在使用 Node/Express 构建一个简单的 REST API,但在将其部署到生产环境时遇到了困难。当NODE_ENV=development 时,一切都按预期工作。我得到了 JSON 错误和正确的状态码。当NODE_ENV=production 时,我只返回一个带有默认错误消息的 HTML 页面,没有别的。我可以读取状态代码,但我需要访问完整的 JSON 有效负载以更好地识别错误。这是我的代码:

import Promise from 'bluebird'; // eslint-disable-line no-unused-vars
import express from 'express';
import config from './config';
import routes from './routes';
import { errorMiddleware, notFoundMiddleware } from './middlewares/error.middleware';
import mongoose from './config/mongoose.config';

// create app
const app = express();

(async () => {
  // connect to mongoose
  await mongoose.connect();

  // pretty print on dev
  if (process.env.NODE_ENV !== 'production') {
    app.set('json spaces', 2);
  }

  // apply express middlewares
  app.use(express.json());

  // register v1 routes
  app.use('/v1', routes);

  // catch errors
  app.use(notFoundMiddleware);
  app.use(errorMiddleware);

  // start server
  app.listen(config.port, () => console.info(`server started on port ${config.port}`));
})();

export default app;

这是notFoundMiddleware

export default (req, res, next) => next(new Error('Not Found'));

这是errorMiddleware

const errorMiddleware = (err, req, res, next) => {
  console.log('test'); // this works in development, but not in production
  const error = {
    status: err.status,
    message: err.message
  };

  if (err.errors) {
    error.errors = err.errors;
  }

  if (process.env.NODE_ENV !== 'production' && err.stack) {
    error.stack = err.stack;
  }

  return res.status(error.status || 500).send({ error });
};

【问题讨论】:

  • em...当你有生产模式时你有if,那么你不会只发送堆栈跟踪消息和状态。if (process.env.NODE_ENV !== 'production' && err.stack) { error.stack = err.stack; }
  • @DmytroMysak 是的,那是因为我不想在生产中使用堆栈。问题是我也没有收到状态或消息。
  • 从 npm 模块文档看来,您必须使用 ApiErrorsMiddleware 才能获得 JSON 响应。
  • 我无法重现您的问题,您能否向我们展示一个示例,说明您返回调用错误处理程序的错误的位置? (例如next(new Error..
  • 您是否在 NGINX 或类似的平台下提供 API?

标签: json node.js api express error-handling


【解决方案1】:

如果您在生产服务器上运行,请尝试使用诸如“papertrailapp”之类的日志记录提供程序来查看您的应用中发生的错误。

【讨论】:

    【解决方案2】:

    我刚刚偶然发现了同样的问题。原来这是由构建生产包时应用的转译器优化引起的 - 这个:https://babeljs.io/docs/en/babel-plugin-minify-dead-code-elimination

    Express 的错误处理程序应具有签名 (err, req, res, next) => { ... }(为 4 位元数)。在您的示例中,next 未在 errorMiddleware 函数体中的任何位置使用,因此它会从生产代码中的函数签名中消除(优化)。

    解决方案

    • 使用keepFnArgs: true 插件选项 - 可能通过https://webpack.js.org/plugins/babel-minify-webpack-plugin/ webpack 配置:

      var MinifyPlugin = require("babel-minify-webpack-plugin")
      module.exports = {
          // ...
      
          optimization: {
              minimizer: [
                  new MinifyPlugin({
                      deadcode: {
                          keepFnArgs: true,
                      },
                  }, {}),
              ],
          }
      
          // ...
      }
      
    • 或者在您的代码中假装使用了此参数:
      const errMiddleware = (err, req, res, _next) => {
          // ... your code ...
          // ...
          // cheat here:
          _next
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 2019-01-31
      • 2015-01-20
      • 2021-07-23
      • 2014-06-13
      相关资源
      最近更新 更多