Express / Node.JS中间件引发错误,继续处理

时间:2012-01-30 14:21:48

标签: node.js asynchronous express

我是从NodeJS / Express开始的,我遇到了以下问题(我可能还没有得到异步编程的所有技巧)

我已经制作了一个中间件,负责检查是否传递了oauth_token参数(实际在我的节点服务器上实现oAuth层)

我这样做:

function myMiddle(req,res,next) {
  var oAuthToken = req.query["oauth_token"];
  if (oAuthToken == undefined) {
            res.send(406);
            res.end();
    next(new Error('No token provided'));   
}
/* Basically doing some DB stuff with MongoDB, connecting and using oAuthToken provided to query, etc.. */

问题在于,当他没有在查询字符串中收到oauth_token参数时,我希望代码“死”。它实际上是在向我提出错误并向我的HTTP客户端返回了大量的406错误,但是代码继续处理并且引发了我之后处理代码导致的可变头错误,并且我的脚本死了。

我遗失的东西?先谢谢。

3 个答案:

答案 0 :(得分:2)

如果您的oAuthToken未定义,Node.js会做出回应。之后,您触发next(...),它会尝试对同一请求做出另一个响应。这失败了,你看到了你所看到的。请注意,在使用res.send();res.end();的Node.js中,不会停止您的功能。所以你需要做的是:

function myMiddle(req,res,next) {
  var oAuthToken = req.query["oauth_token"];
  if (oAuthToken == undefined) {
    next(new Error('No token provided')); // handle everything here

    // res.send(406);
    // res.end();
    // unnecessary, throws errors because you try to respond twice
  }
  // do something if this is fine
}

或以其他方式执行 - 使用res.send(406); res.end();而不使用next(...)

答案 1 :(得分:1)

这可能会迟到,但我刚刚遇到了这个问题。您实际上可以将错误传递给ErrorHandler,以便中间件无法继续下一个中间件或路由器,同时您可以发送所需的HTTP状态代码。

您的中间件

function myMiddle(req, res, next) {
  // Do validate your OAuth token
  // you might want to do better validation of the token here
  // instead of just checking its existence
  //
  // var oAuthToken = req.query['oauth_token'];
  //
  // According to JSLint, you can just directly select the object as:
  //
  // req.query.oauth_token

  if (req.query.oauth_token === undefined) {

    // Just let the ErrorHandler does the rest
    // like redirecting or just send message to client
    var err = new Error('Unauthorized access.');
    err.status(406); // Or 403, or any HTTP status code

    // Pass it to ErrorHandler
    next(err);

  } else {
    // Do something here, or just
    next();
  }
}

您的错误处理程序

app.use(function(err, req, res, next){
  if (err.status == 406) {
    // You can just do res.sendStatus()
    res.sendStatus(406); // Set HTTP status code as 406 and send message to client

    // Or chaining res.status() with res.send()
    res.status(406).res.send(); // or res.render(), or res.json()

    return;

  }

  // Others
});

有关ErrorHandler的更多信息:http://expressjs.com/ja/guide/error-handling.html

答案 2 :(得分:0)

您是否在中间件堆栈中有明确的错误处理(app.use(express.errorHandler())

有关如何使用next()的详细信息,请参阅Express middleware section