AngularJS: Catch all response status 500

前端 未结 3 1437
灰色年华
灰色年华 2020-12-31 05:54

This may seem like a strange request. I was wondering if there is a way using a $http interceptor to catch the first URL that has a response status of 500, then stop all sub

相关标签:
3条回答
  • 2020-12-31 06:01

    You can catch all responses through $httpProvider.responseInterceptors.

    To do this you have to create a factory like this:

    app.factory('SecurityHttpInterceptor', function($q) {
            return function (promise) {
                return promise.then(function (response) {
                    return response;
                },
                function (response) {
                    if (response.status === 500) {
                        //DO WHAT YOU WANT
                    }
                    return $q.reject(response);
                });
            };
        });
    

    In this factory you'll catch the response status if it's 500 do what you want. Then reject the response.

    Now you have to put the factory in the responseInterceptors of $httProvider in your config module like that :

    app.config(function ($routeProvider, $httpProvider) {
        $routeProvider
            .when('/', {
                templateUrl: 'views/home.html',
                controller: 'HomeCtrl'
            })
            .otherwise({
                templateUrl: 'views/404.html'
            });
    
        $httpProvider.responseInterceptors.push('SecurityHttpInterceptor');
    })
    
    0 讨论(0)
  • 2020-12-31 06:02

    Thomas answer is correct, but this solution is currently deprecated. You should do something like this answer.

    app.factory('errorInterceptor', function ($q) {
    
        var preventFurtherRequests = false;
    
        return {
            request: function (config) {
    
                if (preventFurtherRequests) {
                    return;
                }
    
                return config || $q.when(config);
            },
            requestError: function(request){
                return $q.reject(request);
            },
            response: function (response) {
                return response || $q.when(response);
            },
            responseError: function (response) {
                if (response && response.status === 401) {
                    // log
                }
                if (response && response.status === 500) {
                    preventFurtherRequests = true;
                }
    
                return $q.reject(response);
            }
        };
    });
    
    app.config(function ($httpProvider) {
        $httpProvider.interceptors.push('errorInterceptor');    
    });
    
    0 讨论(0)
  • 2020-12-31 06:04

    You could create a service and interceptor to deal with this,

    .factory('ServerErrorService', function() {
    
            var _hasError = false
    
            return {
                get hasError() {
                    return _hasError;
                },
                set hasError(value) {
                    _hasError = value;
                    // you could broadcast an event on $rootScope to notify another service that it has to deal with the error
                },
                clear: clear
            }
    
            function clear() {
                _hasError = false;
            }
    })
    
    
    .factory('ServerErrorInterceptor', function ($q, ServerErrorService) {
    
        var interceptor = {
    
            request: function(config) {
    
                if(ServerErrorService.hasError) {
                    var q = $q.defer();
                    q.reject('prevented request');
                    return q.promise;
                }
                return config;
            },
    
            responseError: function(response) {
    
                if(response.status === 500) {
                    ServerErrorService.hasError = true;
                }
    
                return $q.reject(response);
            }
        }
    
        return interceptor;
    })
    

    If you wanted to allow requests to be made again then you just need to call ServerErrorService.clear()

    OR

    You could use a modified version of this answer. Although i'm not sure how - if you wanted to - you'd cancel this action and allow subsequent requests.

    https://stackoverflow.com/a/25475121/1798234

    .factory('ServerErrorInterceptor', function ($q) {
        var canceller = $q.defer();
        var interceptor = {
    
            request: function(config) {
                config.timeout = canceller.promise;
                return config;
            },
    
            responseError: function(response) {
    
                if(response.status === 500) {
                    canceller.resolve('server error');
                }
    
                return $q.reject(response);
            }
        }
    
        return interceptor;
    })
    

    One thing to remember for both of these solutions, if you have any other interceptors after this that have a responseErrormethod defined or any handlers set up with .catch to process the $http promise, they will receive a response object with {data:null, status:0}

    0 讨论(0)
提交回复
热议问题