Aides
Aides

Reputation: 3683

Angular $http promise always resolving

In every $http call with .then(successFunc) and .catch(errFunc) (alternatively then(successFunc, errFunc) the then/success is always called (the promise is successfully resolved).

Example

$http.get('/some/resource') 
//   /some/resource --> HTTP 400
    .then(function(response)
    {
        console.log('success');
    })
    .catch(function(reason)
    {
        console.log('error');
    })

// Console: 
// - success

Is this the intended behaviour or what causes this?

Upvotes: 1

Views: 495

Answers (2)

georgeawg
georgeawg

Reputation: 48968

Your example converts a rejection to a resolved promise.

$http.get('/some/resource') 
//   /some/resource --> HTTP 400
    .then(function(response)
    {
        console.log('success');
        //IMPORTANT -- return to chain data
        return response;
    })
    .catch(function(reason)
    {
        console.log('error');
        //IMPORTANT -- throw to chain rejections
        throw reason;
    })

When a catch handler omits a throw statement, the function returns undefined which converts the rejection to a promise that resolves undefined.

Look in your code for a http interceptor that is following the same erroneous pattern.

The rule in functional programming is always return (or throw) something.

Upvotes: 1

Aides
Aides

Reputation: 3683

No, this is not intended behaviour. Normally it should call .then() on HTTP 2xx and .catch() on HTTP 4xx and HTTP 5xx (not sure about the others).

The described behaviour is probably caused by another .catch() returning a resolved promise.

In a slightly changed example:

//In some Service:
function getResources()
{
    $http.get('/some/resource') 
    //   /some/resource --> HTTP 400
        .then(function(response)
        {
            console.log('service success');
            return response;
        })
        .catch(function(reason)
        {
            console.log('service error');
            // IMPORTANT: although this is returned 
            // in a .catch() it returns a resolved promise
            return reason;
        });
}

//In some Controller:
someService.getResources()
    .then(function(response)
    {
        console.log('controller success');
    })
    .catch(function(reason)
    {
        console.log('controller error');
    });


// Console:
// - service error
// - controller success

Note that this can also be caused by a registered http interceptor:

$httpProvider.interceptors.push(function($q)
{
    return {
        'response': function(response)
        {
            // do something
            return response;
        },
        'responseError': function(rejection)
        {
            // do something
            return rejection; // <-- this causes the problem
            // instead do
            return $q.reject(rejection);
        }
    }
}

Upvotes: 1

Related Questions