Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retry failed requests with $http interceptor

The API my webapp is talking to sometimes overloads and is sending 500 Internal Server Error if it cannot handle request.

There are 100+ different requests my web application can send, so if I implement retry on each individually, it will cost me hours of typing.

I'm already using $httpProvider interceptor, here it is (simplified)

$httpProvider.interceptors.push(function ($q) {
    return {
        responseError: function (response) {
            switch (response.status) {
                case 401 :
                    window.location = "/";
                    alert('Session has expired. Redirecting to login page');
                    break;
                case 500 :
                    // TODO: retry the request
                    break;
            }
            return $q.reject(response);
        }
    };
});

How could I resend a request after getting 500 response code from the server?

like image 218
Dan Avatar asked Sep 15 '15 14:09

Dan


People also ask

How do I retry any failed HTTP request with angular interceptor?

As you probably already know this interceptor can be used to modify any incoming or outgoing HTTP requests. How do we get the benefits of an Angular interceptor and use it to retry any failed HTTP request? The answer is simple. To add the retry capability we'll use the retry function that triggers a retry when the Observable fails.

What are interceptors in httpclient?

Interceptors allow us to intercept incoming or outgoing HTTP requests using the HttpClient. They can handle both HttpRequest as well as HttpResponse. By intercepting the Http request, we can modify or change the value of the request, and by intercepting the response, we can do some predefined actions on a particular status code or message.

What is the use of error interceptor?

An error interceptor is a special kind of interceptor used for handling errors that happen when making HTTP requests. Errors come either from the client-side (browser) or the server-side when the request fails for some reason. If the request fails on the server, HttpClient returns an error object instead of a successful response.

How many times can an HTTP request be retried?

Now if any HTTP request fails it will retry that request another 3 times. How do you retry on certain response status codes?


1 Answers

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.

like image 97
S.Klechkovski Avatar answered Oct 12 '22 12:10

S.Klechkovski