简体   繁体   English

如何正确处理请求承诺错误?

[英]How to handle request-promise errors properly?

So I'm using request-promise in a script that I have that loops through a list of urls and fires of requests. 所以我在一个脚本中使用了request-promise ,这个脚本循环遍历url和请求的激活列表。 Then I want to do something w/ the data received once all the requests are complete. 然后,我希望在所有请求完成后,接收数据。

I have the following: 我有以下内容:

var rp = require('request-promise');

rp.get({
    uri: 'http://httpstat.us/500',
    transform: function(body, res){
        res.data = JSON.parse(body);
        return res;
    }
}).then(function(res){
    results.push(res.data);
})
.catch(function(err){
    should.throw.error.to.console();
    var respErr  = JSON.parse(err.error);
    var errorResult = {
        origUrl: respErr.origUrl,
        error: respErr
    };
    results.push(errorResult);
});

As you can see.. http://httpstat.us/500 throws a 500, which causes the .catch() block to be ran. 正如你所看到的.. http://httpstat.us/500抛出一个500,这将导致.catch()块中跑去。 I'm forcing an error. 我在逼错。 should.throw.error.to.console(); should throw an error to the console, but instead, the script just exits silently w/o any error code ( Process finished with exit code 0 ). 应该向控制台抛出一个错误,但是,脚本只是静默退出没有任何错误代码( Process finished with exit code 0 )。

I'm assuming that request-promise is catching the error from node's http when a page doesn't come back w/ 2xx code and then passing that back to the catch() callback. 我假设当一个页面没有返回w / 2xx代码然后将其传递回catch()回调时,请求承诺正在从节点的http捕获错误。 But any subsequent errors then end up failing silently. 但任何后续错误最终都会以无声的方式失败。 How in the world do I handle this so that the rest of my code will still throw errors properly? 我如何处理这个问题,以便我的其余代码仍能正确抛出错误?

Related GitHub issue 相关的GitHub 问题

What do you mean by "any subsequent errors then end up failing silently"? 什么是“任何后续错误然后最终失败”的意思是什么? If the original promise rp fails, the catch executes… at the time of failure. 如果原始promise rp失败,则catch 失败时执行.... Once a promise is rejected, that's it, there can be no "subsequent errors." 一旦承诺被拒绝,就是这样,就不会有“后续错误”。

Also, should looks like an assertion (eg from chai ) which would suggest that you are trying to test this. 此外, should看起来像一个断言(例如从chai ),这表明你试图测试这个。 Chai's should.throw doesn't throw an error, it checks that an error has been thrown. Chai的should.throw不会抛出错误,它会检查是否抛出了错误。 If you are testing this, you need to indicate to the test ( it block) that the test is async, not sync — usually by naming & invoking a done parameter. 如果您正在测试它,您需要指示测试( it阻止)测试是异步的,而不是同步 - 通常是通过命名和调用done参数。 Otherwise, the request will be sent out, and then before ANY response can be made, the script will synchronously end and no errors will be listened for. 否则,将发出请求,然后在可以做出任何响应之前,脚本将同步结束并且不会收听任何错误。

What's more, you are spec'ing that something should throw to console, but nothing in your code throw s! 更重要的是,你正在指出某些东西应该throw控制台,但你的代码中没有任何东西throw If you DID write in a throw , you should understand that throw inside a then or catch will simply cause the outgoing promise from that handler to be rejected with the thrown value (yes, catch exports a new promise, just like then — it is 100% sugar for .then(null, errHandler) . If you want errors to be re-thrown back into the window, you need to finalize the chain with Bluebird's .done() promise method, accessed in request-promise via the somewhat arcane .promise().done() . But even in that case you'd still need to specify that you're doing an async test. 如果你没有在写throw ,你应该明白, throw里面thencatch将会使得从处理器传出的承诺与抛出值(是的,拒绝catch出口新的承诺,就像then -这是100 .then(null, errHandler) %糖。如果你想将错误重新抛回窗口,你需要使用Bluebird的.done() promise方法完成链,通过有点神秘的方式在request-promise中访问.promise().done() 。但即使在这种情况下,您仍然需要指定您正在进行异步测试。

In short, it's not entirely clear what you think some of this code is supposed to be doing, and how it differs from your expectations. 简而言之,您认为某些代码应该在做什么以及它与您的期望有何不同并不完全清楚。 Please clarify! 请澄清!

var rp = require('request-promise');

rp.get({ // start an async call and return a promise
    uri: 'http://httpstat.us/500',
    transform: function(body, res){
        res.data = JSON.parse(body);
        return res;
    }
}).then(function(res){ // if rp.get resolves, push res.data
    results.push(res.data);
})
.catch(function(err){ // if rp.get rejects (e.g. 500), do this:
    should.throw.error.to.console(); // test if something is thrown (but nothing has been!)
    var respErr  = JSON.parse(err.error);
    var errorResult = {
        origUrl: respErr.origUrl,
        error: respErr
    };
    results.push(errorResult); // push an object with some of the error info into results
});

// this line (e.g., end of script) is reached before any of the async stuff above settles. If you are testing something, you need to make the test async and specify when it's complete by invoking `done()` (not the same as ending the promise chain in Bluebird's `.done()`).

So apparently the .catch() in promises is basically a wrapper around a JS try-catch. 很明显,promises中的.catch()基本上是JS try-catch的包装器。 So in order to have subsequent errors logged to the console after already having written one handler, you have to have a second handler to throw the eventual error to the console. 因此,为了在已经编写了一个处理程序后将后续错误记录到控制台,您必须有第二个处理程序将最终错误抛出到控制台。

More info on GitHub here: https://github.com/request/request-promise/issues/48#issuecomment-107734372 有关GitHub的更多信息,请访问: https//github.com/request/request-promise/issues/48#issuecomment-107734372

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM