[英]Bluebird Javascript Promise: stop execution after dealing with specified error
我有一个稍微复杂的流程,该entryUrl
从数据库接收一个entryUrl
,检查它重定向到的位置,然后使用exitUrl
更新它。
基本上,流程应如下所示:
Url
没有离开网址
request
获取Url.entryUrl
的标头
Url
并继续下一个 request
产生的exitUrl
exitUrl
Url
Url
请在5秒钟后重试 我当前的实现是这样的,使用Bluebird javascript promise样式:
function processNext() {
return api.getUrlWithoutExitUrl()
.then(function followEntryUrl(url)
{
if (!url || !url.entryUrl)
{
throw new NoUrlAvailableError();
}
log.info('getting exit url for ' + url.entryUrl);
return [
request({
method : 'HEAD',
url : url.entryUrl,
followAllRedirects : true,
maxRedirects : 20
})
.catch(ResponseError, function()
{
log.error('got strange response');
})
.catch(ConnResetError, function()
{
log.error('connection was reset');
})
.then(function removeInvalidUrl()
{
log.info('remove invalid url'); //FIXME: after doing this, we should not continue with the other `then` calls
}),
url
];
})
.spread(function parseExitUrl(res, url)
{
if (!res[0] || !res[0].request || !res[0].request.uri || !res[0].request.uri.href)
{
throw new InvalidUrlError();
}
return [res[0].request.uri, url];
})
.spread(function storeExitUrl(parsedExitUrl, url)
{
return api.setUrlExitUrl(url, parsedExitUrl);
})
.then(processNext)
.catch(InvalidUrlError, function()
{
log.info('an attempted url is invalid, should set as processed and continue with next immediately');
})
.then(processNext)
.catch(NoUrlAvailableError, function()
{
log.info('no url available, try again after a while');
})
.delay(5000)
.then(processNext)
.catch(function(err)
{
log.error('unexpected error, try again after a long while');
log.error(err);
log.error(err.constructor);
})
.delay(60000)
.then(processNext);
}
processNext();
function ResponseError(e)
{
return e && e.code === 'HPE_INVALID_CONSTANT';
}
function ConnResetError(e)
{
return e && e.errno === 'ECONNRESET';
}
现在的问题是,如果存在ConnResetError
或ResponseError
,则catch块将按应有的方式执行,但是spread
调用then
块也将被执行-但我希望在捕获到这些内容之后做一些事情后停止执行2种特定的错误类型。
我将如何实现这种执行流程?
就像在同步代码-如果你有一个catch
要在其中进行一些处理,然后传播错误-你可以重新抛出:
同步代码:
try {
a = makeRequest();
} catch(e) {
// handle
throw e;
}
承诺:
makeRequest().catch(e => {
// handle
throw e; // also a good idea to add data to the error here
});
从内部的诺言中,当您第一次catch
ResponseError或ConnResetError时,您通常会返回(即不抛出),因此后续的诺言链成功,执行了then()
和spread()
分支,而不是失败并转到catch()
分支机构。
您可能希望像这样重写内部的诺言catch
块:
...
.catch(ResponseError, function(err) {
log.error('got strange response');
throw err;
})
...
基本上,重新抛出Error
,如果你想继续把它当作一个错误:你抓了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.