1

I'm building my first Angular app, and I've run into a problem. I have an AngularJS resource whose .get I call with both a success and error callback, like so:

var new_uptime = Uptime.get({}, function(){
    console.log("new_uptime", new_uptime, "$scope.uptime", $scope.uptime);
    console.log("new_uptime.uptime", new_uptime.uptime);
    if ($scope.uptime && new_uptime.uptime < $scope.uptime.uptime) {
        console.log("Reboot detected");
        location.reload(true);
    }
    $scope.uptime = new_uptime;
    $timeout(reload_uptime, 5000);
}, function(response){
    console.log("Failed to read uptime", response);
    console.log("Retrying in 10s");
    $scope.uptime = "[unknown]";
    $timeout(reload_uptime, 10000);
}); 

I've tested this with various error statuses from the server, and it works fine. Now I'd like to add app-wide retrying on 503s. I've added a module for that, which looks like this:

retry_module = angular.module('service.retry', []);
retry_module.factory("retry", ["$q", "$injector", "$timeout", function($q, $injector, $timeout) {
    return {
        "responseError": function(rejection) {
            console.log("Request failed", rejection);
            if (rejection.status != 503) {
                console.log("Unhandled status");
                return $q.reject(rejection);
            }
            var delay = Math.floor(Math.random() * 1000);
            console.log("Was 503, retrying in " + delay + "ms");
            var deferred = $q.defer();
            $timeout(function() {
                var $http = $http || $injector.get("$http");
                deferred.resolve($http(rejection.config));
            }, delay);
            return deferred;
        }
    };
}]);
retry_module.config(["$httpProvider", function ($httpProvider) {
    $httpProvider.interceptors.push("retry");
}]);

This works well for retrying on 503s, and successful attempts are handled by the success callback in the Uptime.get caller, as intended. However, if the server returns some other error, then I get the "Unhandled status" printout, but then neither "new_uptime" nor "Failed to read uptime". Where did my rejection go, and how do I go about trouble-shooting issues like this?

1 Answer 1

2

You need to return the promise, not the deferred. So the end of your responseError handler should be:

        var deferred = $q.defer();
        $timeout(function() {
            var $http = $http || $injector.get("$http");
            deferred.resolve($http(rejection.config));
        }, delay);
        return deferred.promise;
Sign up to request clarification or add additional context in comments.

2 Comments

Right. It seems that this problem was causing my printouts to not match what I was expecting. Re-rejecting the non-503 responses (which was my concern) was actually working, but I didn't see it because of the issue you pointed out. Thanks!
In my case, I was just returning the response instead of re-rejecting it, which produced the same issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.