【发布时间】:2015-01-13 03:14:52
【问题描述】:
我正在实现一个 node + express js 应用程序,但在错误处理程序中调用 next 函数时遇到问题。
我有一个render 中间件,每个控制器中的next 都会调用它,我希望它与我的错误处理程序相同。我在控制器中所做的是将一些 viewProperties 放在 req 中,然后调用下一个中间件来检索这些属性并因此呈现响应。
function render(req, res, next) {
// viewName, title, args
var properties = req.viewProperties || {};
// We only handle a res.send(message)
if (properties.body) {
res.send(properties.body);
return;
}
// We only handle a res.redirect(url)
if (properties.redirect) {
res.redirect(properties.redirect);
return;
}
properties.lang = req.app.get('lang');
properties.title = properties.title || 'Message_Me';
properties.connected = req.session ? req.session.connected : false;
properties.firstname = req.session.userFirstname || 'anonymous';
res.render(properties.name, properties);
}
当我尝试将此中间件与我的错误处理程序一起使用时,使用next() 请求只是在客户端挂起,并且从未收到。
因此,我尝试创建与错误处理程序相同的中间件:相同的函数,但元数为 4,然后在我的错误处理程序中调用 next(err)。这次响应被客户端重新审核,但没有正确呈现,它只显示堆栈跟踪。
我找到的唯一方法是将这个函数复制到我的错误处理程序中并将其粘贴,而不是调用next。我不明白为什么它不能正常工作?
我的错误处理程序:
function redirectError(err, req, res, next) {
// Ajax call running
if (req.xhr) {
req.viewProperties = { body : err.message };
return next(err);
}
req.viewProperties = { name : 'layout/error', title : 'Erreur', message : err.message, err : err };
// Here is the probleme
next()
// next(err);
}
编辑
我尝试了另一件事:我将render 方法作为一个简单函数(未声明的中间件)复制到了我的错误模块中。然后在redirectError 错误处理程序中调用它而不是next。做了同样的行为。该函数被调用,但客户端没有收到任何内容。
鉴于
如果我将render 函数的内容复制到redirectError 中,一切正常。
这里确实有一些我不明白的地方。这可能是一个我还没有注意到的更深层次的问题...... 黑暗之谜
编辑 N2
我发现了我的错误!我忘记了另一个中间件的if 中的return 语句。这使得next被调用了两次,这是一种非常糟糕的行为......
作为结论,一个好的做法是在调用 next 时始终使用return!
感谢 laggingreflex 让我继续前进。
【问题讨论】:
-
redirectError是最后一个中间件吗?如果是这样,就没有什么可以转到next了,所以不知道你为什么要打电话。 -
最后一个中间件是
render。它是在redirectError之后设置的,所以确实有下一个可以去。我什至用日志对其进行了测试,render中间件正确打印了它
标签: javascript node.js express error-handling