[英]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.