I've got a somewhat complicated flow that receives an entryUrl from a database, checks where it redirects to, and then updates it with an exitUrl.
Basically the flow should be like so:
- retrieve an 
Urlwithout an exit url- get the 
Url.entryUrl's headers usingrequest- if there's an unexpected response or connection was reset, flag this 
Urland continue with the next one 
 - if there's an unexpected response or connection was reset, flag this 
 - parse the 
exitUrlresulting from therequestperformed- store the 
exitUrl - continue with the next 
Url 
 - store the 
 
 - get the 
 - if no 
Urlavailable, try again after 5 seconds - if any unexpected error in the above chain or subchains, try again after 60 seconds
 
My current implementation is like so, using the Bluebird javascript promise style:
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';
}
Now, the problem is that if there's a ConnResetError or a ResponseError, the catch blocks are executed as they should be, but the then blocks following the spread call are also executed -- yet I want execution to stop after having done something after catching these 2 specific error types.
How would I achieve such flow of execution?
                        
Just like in synchronous code - if you have a
catchin which you want to perform some processing and then propagate the error - you can rethrow it:Synchronous code:
With promises: