当NODE_ENV = production时,错误处理程序将被忽略

时间:2018-08-11 10:54:05

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

我正在使用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 });
};

2 个答案:

答案 0 :(得分:0)

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

enter image description here

答案 1 :(得分:0)

我偶然发现了同样的问题。原来,这是由于在构建生产包时应用了Transpiler优化所致-这个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
    }