【问题标题】:Express/Node.JS middleware raising error, keeps processingExpress/Node.JS 中间件引发错误,继续处理
【发布时间】:2012-02-22 07:54:40
【问题描述】:

我从 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 参数时,我预计代码会“死掉”。它实际上向我提出了一个错误并将 406 错误返回给我的 HTTP 客户端,但是代码一直在处理后面并引发了我的处理代码导致的可变标头错误,并且我的脚本死了。

我错过了什么?提前致谢。

【问题讨论】:

    标签: node.js asynchronous express


    【解决方案1】:

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

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

    【讨论】:

    • 是的,我有错误处理程序。实际上我通过返回 next('error') 而不是仅仅调用 next 来“解决”(不确定它是否干净)。我想这是有道理的,因为它使函数退出
    【解决方案2】:

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

    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(...)

    【讨论】:

    • 我也试过了,代码继续处理。就像我在下面的评论中说的那样,我通过返回 next('error') 而不是仅仅调用它来修复它。你觉得这合乎逻辑吗?
    • 它没有。 :D 实际上确实如此,这仅意味着您在调用next() 后强制该函数停止工作。也许你应该修改一下我的代码并使用if {...} else {...}?重要的是,在next() 之后没有任何内容(与响应有关)。我只能说,祝你好运!
    【解决方案3】:

    这可能会迟到,但我也遇到了这个问题。您实际上可以将错误传递给 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

    【讨论】:

      猜你喜欢
      • 2013-03-20
      • 2017-09-07
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-30
      • 1970-01-01
      相关资源
      最近更新 更多