【问题标题】:Node.js Express Middleware Error ChainNode.js Express 中间件错误链
【发布时间】:2016-04-30 11:03:28
【问题描述】:

我必须从网页上抓取一个密钥,以便以后用作 cookie。那部分有效。但是因为请求是异步的,所以不会处理错误。我想确保错误通过中间件链传递。但我无法理解这个问题。感谢您的帮助。

app.use('/', makeLoginCookie, function (req, res, next){
    console.log('My app.use() starts here.');
    //console.log('makeLoginCookie: %s', err);
    next(); 
});

这是函数

function makeLoginCookie(req, res, next) {
    httpOptions = {
        url: site.url,
        headers: {
            Cookie: null
        }
    }

// Get HIDDEN key, build login cookie
request(httpOptions, function(error, response, body) {
    if (!error && response.statusCode == 200) {
        //console.log(body)
        var match = body.match( /\<INPUT TYPE=HIDDEN id=\"key\", value=\"([0-9a-f]+)\"\>/i );
        var key = match[1]
        var encrypted = sha1(key + site.username + site.password);
        loginCookie = "username=" + key + ";password=" + encrypted;
        next();
    } else {
        console.log("Connect failed %s" , error);
        //err = new Error("Can't connect");
        next();
    }
  });
};

【问题讨论】:

    标签: node.js asynchronous express


    【解决方案1】:

    参考Express Error handling,可以使用next(err);传递Express中的错误。 Here 是一个很好的链接。

    【讨论】:

    • 我遇到的问题比next(err) 更复杂,我尝试并评论了这一点,如我最初的帖子所示。再看看我的app.use() 并注意makeLoginCookie 是如何放置的。这解决了我的异步问题,但似乎破坏了错误处理。 @Renan
    • 为什么更复杂?当makeLoginCookie()发生错误时调用next(error)
    • 由于某种原因,当我这样做时,我的应用程序只是锁定了。我有 Express 提供的正常错误处理,我希望它会落入堆栈并给出 500 错误。但它卡在某个地方。任何想法如何追踪它被卡住了?
    • 不知道为什么,但我把err = new Error("Can't connect"); next(err); 放回去,它按预期工作。
    【解决方案2】:

    我会使用promises (Q library) 来解决这个问题,以及其他事情,特别是用于网络抓取。您的“makeLoginCookie”函数可能会返回一个 deferred.promise,并且当请求失败时,会以错误拒绝它。

    编辑 1:我推荐这个很棒的视频,它解释了如何使用异步代码 https://www.youtube.com/watch?v=obaSQBBWZLk 正常工作。它可以帮助您解决这个问题和其他问题。

    编辑2:使用promise会是这样,看看是否对你有帮助:

    var Q = require("q");
    
    app.use('/', function (req, res, next) {
    
        // This part, we will call your function "makeLoginCookie"
        makeLoginCookie().then(function(){
            // This is called when your function RESOLVES the promise
    
            // Here you could log or do some stuff...
    
            // Then, go next...
            next();
        }, function(error){
            // This is called when your function REJECTS the promise
            console.log("Connect failed %s" , error);
    
            // And then, handle the error, like stopping the request and sending an error:
            res.status(400).json({errorMessage: error});
        })
    }, function (req, res, next){
        console.log('My app.use() starts here.');
        next(); 
    });
    
    // Removed parameters from function
    function makeLoginCookie() {
        // This is the object that will return a promise
        var deferred = Q.defer();
    
        httpOptions = {
            url: site.url,
            headers: {
                Cookie: null
            }
        }
    
        // Get HIDDEN key, build login cookie
        request(httpOptions, function(error, response, body) {
            if (!error && response.statusCode == 200) {
                //console.log(body)
                var match = body.match( /\<INPUT TYPE=HIDDEN id=\"key\", value=\"([0-9a-f]+)\"\>/i );
                var key = match[1]
                var encrypted = sha1(key + site.username + site.password);
                loginCookie = "username=" + key + ";password=" + encrypted;
    
                // Instead of using next(), RESOLVE your promise
                // next();
                deferred.resolve(); // You can pass some data into it..
            } else {
    
                // Instead of using next(), REJECT your promise
                // next();
                deferred.reject(error); // You can pass some data into it, like an error object or string...
            }
        });
    
        // Promise that something will be fulfilled or reject later
        return deferred.promise;
    };
    

    【讨论】:

    • 那个视频很棒。让我停下来考虑回到我以前的 php 方式,因为 js 快把我逼疯了。
    • 总之,这对我帮助很大!我已经用一个使用承诺来解决您的问题的示例编辑了我的答案。看看有没有帮助。
    • 这真的很有趣。当我开始工作时,我会尝试并标记帖子已回答。谢谢!
    【解决方案3】:

    我的代码中的其他地方一定有一些错误,因为它现在按预期工作。

    } else {
        console.log("Connect failed %s" , error);
        err = new Error("Can't connect");
        next(err);
    }
    

    【讨论】:

      猜你喜欢
      • 2012-02-22
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      • 2022-01-17
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多