Search code examples
angularjsinternet-explorerinternet-explorer-10

IE10 interprets status codes 401/403 as network error


I have an AngularJS responseError interceptor that broadcasts events for 401 and 403 HTTP status codes. But there is a bug in IE10 (according to this) when it gets a 401 status code from the server (not logged in) or 403 (not authorized), IE interprets this as a network error, so the responseError interceptor is never fired, thus the user is never redirected to the login page.

Code:

app.factory('authHttpInterceptor', ["$rootScope", "AUTH_EVENTS", "$q", function ($rootScope, AUTH_EVENTS, $q) {
    return {
        'request': function (config) {
            return config;
        },
        'requestError': function (rejection) {
            return $q.reject(rejection);
        },
        'response': function (response) {
            return response;
        },
        'responseError': function (rejection) {
            $rootScope.$broadcast({
                401: AUTH_EVENTS.notAuthenticated,
                403: AUTH_EVENTS.notAuthorized
            }[rejection.status], rejection);
            return $q.reject(rejection);
        }
    };
}]);

Here's a screenshot:

http://i.imgur.com/8iZQjFM.png

Is there any solution to this?

Edit: response interceptor is fired and I was going to check there if the status was 401 or 403 and then broadcast it from there, but it's only fired if the response is a success (200 OK).

Edit 2: It turns out the responseError interceptor gets called, but with status code 0.

Edit 3: I'm solving this by adding 0: AUTH_EVENTS.notAuthenticated, because if we receive HTTP status code 0, clearly something is wrong.


Solution

  • This is a bug in Internet Explorer 10 and was closed by Microsoft as not reproducible. The bug lets IE interpret 401 status codes from the server as a network error, so it's impossible to determine whether the user is unauthorized or simply lost internet connection.

    I solved this by adding 0 as an error event, so when receiving status code 0 it broadcasts the notAuthenticated event. According to RFC 2616 there is no status code 0 so when receiving it, means something went wrong.

    I changed the interceptor to the following:

    'responseError': function (rejection) {
        $rootScope.$broadcast({
            0: AUTH_EVENTS.notAuthenticated, // Edge case, if status code from server is 0, clearly something is wrong
            401: AUTH_EVENTS.notAuthenticated,
            403: AUTH_EVENTS.notAuthorized
        }[rejection.status], rejection);
        return $q.reject(rejection);
    }