当 NODE_ENV=production 时忽略错误处理程序
Posted
技术标签:
【中文标题】当 NODE_ENV=production 时忽略错误处理程序【英文标题】:Error handler ignored when 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?
【参考方案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
【讨论】:
以上是关于当 NODE_ENV=production 时忽略错误处理程序的主要内容,如果未能解决你的问题,请参考以下文章
if(process.env.NODE_ENV === 'production') 总是假的
if(process.env.NODE_ENV ==='production')总是假的
使用带有 NODE_ENV=production 的 spawn 函数