Javascript 快速:调用错误处理程序中的下一个
我正在实现一个node+express js应用程序,在错误处理程序中调用Javascript 快速:调用错误处理程序中的下一个,javascript,node.js,express,error-handling,Javascript,Node.js,Express,Error Handling,我正在实现一个node+express js应用程序,在错误处理程序中调用next函数时遇到问题 我在每个控制器中都有一个render中间件,由next调用,我希望我的错误处理程序也一样。我在controler中所做的是将一些viewProperties放入req中,然后调用下一个中间件来检索这些属性并呈现相应的响应 function render(req, res, next) { // viewName, title, args var properties = req.viewP
next
函数时遇到问题
我在每个控制器中都有一个render
中间件,由next
调用,我希望我的错误处理程序也一样。我在controler中所做的是将一些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()
客户端的请求只是挂起的,从未收到。
因此,我尝试创建与错误处理程序相同的中间件:相同的函数,但arity为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
方法作为一个简单的函数(不是声明的中间件)复制到我的错误模块中。然后调用它,而不是重定向错误
错误处理程序中的next
。那也有同样的行为。调用了该函数,但客户端未接收任何内容
鉴于
如果我将render
函数的内容复制到redirectError
中,一切正常
我真的有点不明白。这可能是一个更深层次的问题,我还没有注意到。。。
黑暗中的谜语
编辑N2
我发现了我的错误!!我忘记了另一个中间件的if
中的return
语句。这使得下一个被调用了两次,而且是一个非常糟糕的行为
总之,一个好的做法是在调用next时始终使用return
感谢LaggingReflect,这让我继续了下去。如果存在错误(抛出或通过next
)则只调用下一个可以处理错误的中间件(使用(err,req,res,next)
)定义的中间件)
相反,如果不存在错误,则不会调用错误处理程序中间件(err,req,res,next)
因此,在您的情况下,仅当存在错误时才会调用redirectError
,而只有当不存在错误时才会调用render
证明:
app.use(function(req, res, next) {
throw(new Error('testing...'));
});
app.use(function(req, res, next) {
// This won't be called
});
app.use(function(err, req, res, next) {
// But This would
next(); // not passing any Error this time
});
app.use(function(err, req, res, next) {
// So now this won’t be called
});
app.use(function(req, res, next) {
// But this would
});
如果存在错误(抛出或通过next
)传递),则只调用能够处理错误的下一个中间件(使用(err,req,res,next)
的arity定义的中间件)
相反,如果不存在错误,则不会调用错误处理程序中间件(err,req,res,next)
因此,在您的情况下,仅当存在错误时才会调用redirectError
,而只有当不存在错误时才会调用render
证明:
app.use(function(req, res, next) {
throw(new Error('testing...'));
});
app.use(function(req, res, next) {
// This won't be called
});
app.use(function(err, req, res, next) {
// But This would
next(); // not passing any Error this time
});
app.use(function(err, req, res, next) {
// So now this won’t be called
});
app.use(function(req, res, next) {
// But this would
});
redirectError
是最后一个中间件吗?如果是这样的话,就没有什么要转到下一个的,所以不知道为什么要调用它。最后一个中间件是render
。它是在重定向错误后设置的,因此确实有一个下一步要去。我甚至用日志对它进行了测试,渲染
中间件正确地打印它重定向错误
是最后一个中间件吗?如果是这样的话,就没有什么要转到下一个的,所以不知道为什么要调用它。最后一个中间件是render
。它是在重定向错误后设置的,因此确实有一个下一步要去。我甚至用日志和渲染
中间件对它进行了测试,正确地打印出来。谢谢你的回答,但我知道这一点。实际上,正如我在前面的评论中所说,我将日志放在render
方法中,它们都在经过错误处理程序后打印到最后一行。这意味着调用了res.render(…)
,但请求在客户端处于挂起状态,我从未得到任何响应。我不明白为什么…我明白了,我本想发表一个评论,但时间太长了。无论如何。您可以呈现
日志(打印在客户端?),那么请求如何仍然挂起?我忘了说它只是服务器端日志。我在render方法中输入了一些consol.log()
,在传入redirectError
后,它们被很好地打印在我的服务器控制台上。这意味着对next()
的调用运行良好,res.render(properties.name,properties)实际上调用了code>。但我从来没有收到过客户方面的任何东西。。。是否有我不适用的回复格式要求,或其他要求?对我来说,这真是一种奇怪的行为。我明白了。什么是properties.name,properties
?另外,请尝试在渲染后放置另一个错误处理程序中间件,以查看是否引发了任何错误。如果你可以看一下的话<代码>属性
是一个包含视图模型信息的对象(我使用jade)。它取自req
。我把它放在整个中间件流程的req
中。谢谢你的回答,但我知道。实际上,正如我在前面的评论中所说,我将日志放在render
方法中,它们都在经过错误处理程序后打印到最后一行。这意味着调用了res.render(…)
,但请求在客户端处于挂起状态,我从未得到任何响应。我不明白为什么…我明白了,我本想发表一个评论,但时间太长了。无论如何。您可以呈现
日志(打印在客户端?),那么请求怎么还挂起?我忘了