Retry failed requests with $http interceptor

喜欢而已 提交于 2019-12-03 05:46:12
S.Klechkovski

Angular provides reference to the config object which was used by $http service for doing the request in the response (response.config). That means if we can inject $http service in the interceptor we can easily resend the request. Simple injecting of $http service in the interceptor is not possible because of the circular dependency but luckily there is a workaround for that.

This is an example how the implementation of a such interceptor can be done.

$httpProvider.interceptors.push(function ($q, $injector) {
    var incrementalTimeout = 1000;

    function retryRequest (httpConfig) {
        var $timeout = $injector.get('$timeout');
        var thisTimeout = incrementalTimeout;
        incrementalTimeout *= 2;
        return $timeout(function() {
            var $http = $injector.get('$http');
            return $http(httpConfig);
        }, thisTimeout);
    };

    return {
        responseError: function (response) {
            if (response.status === 500) {
                if (incrementalTimeout < 5000) {
                    return retryRequest(response.config);
                }
                else {
                    alert('The remote server seems to be busy at the moment. Please try again in 5 minutes');
                }
            }
            else {
                incrementalTimeout = 1000;
            }
            return $q.reject(response);
        }
    };
});

Note: In this example implementation the interceptor will retry the request until you receive a response with status that is different than 500. Improvement to this can be adding some timeout before retrying and retrying only once.

You can check for any possible server side errors by expanding the status code check a little more. This interceptor will attempt to retry the request multiple times and will do so on any response code 500 or higher. It will wait 1 second before retrying, and give up after 3 tries.

$httpProvider.interceptors.push(function ($q, $injector) {

    var retries = 0,
        waitBetweenErrors = 1000,
        maxRetries = 3;

    function onResponseError(httpConfig) {
        var $http = $injector.get('$http');
        setTimeout(function () {
            return $http(httpConfig);
        }, waitBetweenErrors);
    }

    return {
        responseError: function (response) {
            if (response.status >= 500 && retries < maxRetries) {
                retries++;
                return onResponseError(response.config);
            }
            retries = 0;
            return $q.reject(response);
        }
    };
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!