Express : 在错误处理程序中调用 next
Express : Call to next in error handler
我正在实现一个 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
被调用了两次,并且行为非常糟糕...
总而言之,一个好的做法是在下次调用时始终使用 return
!
感谢 laggingreflex 让我坚持下去。
如果存在错误(抛出或通过 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
});
我正在实现一个 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
被调用了两次,并且行为非常糟糕...
总而言之,一个好的做法是在下次调用时始终使用 return
!
感谢 laggingreflex 让我坚持下去。
如果存在错误(抛出或通过 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
});