Express : 在错误处理程序中调用 next

1 javascript error-handling node.js express

我正在实现一个 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);
}
Run Code Online (Sandbox Code Playgroud)

当我尝试将这个中间件与我的错误处理程序一起使用时,使用next()请求只是在客户端挂起,从未收到。因此,我尝试创建与错误处理程序相同的中间件:相同的函数但数量为 4,然后调用next(err)我的错误处理程序。这一次响应在客户端被 revived 但它没有正确呈现,它只显示堆栈跟踪。

我发现的唯一方法是将这个函数复制到我的错误处理程序中并粘贴它而不是调用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);
}
Run Code Online (Sandbox Code Playgroud)

编辑

我尝试了另一件事:我将该render方法作为一个简单的函数(未声明的中间件)复制到我的错误模块中。然后调用它而不是nextredirectError错误处理程序中。做了同样的行为。该函数被调用,但客户端没有收到任何内容。

然而

如果我将render函数的内容复制到INTO 中,redirectError一切正常。

这里真的有一些我不明白的地方。这可能是一个我还没有注意到的更深层次的问题...... 黑暗中的谜语

编辑 N2

我发现了我的错误!!我忘记了另一个中间件的return声明if。这使得这个next人被叫了两次,而且是一个非常糟糕的行为......

总之,一个好的做法是return在调用 next 时总是使用!

感谢laggingreflex,它让我继续前进。

lag*_*lex 5

如果存在错误(抛出或通过next),则仅(err,req,res,next)调用下一个可以处理错误的中间件(用 arity of 定义的中间件)。

相反,如果没有错误存在,那么错误处理中间件(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
});
Run Code Online (Sandbox Code Playgroud)