Ho un gestore di errori globale per la mia app angolare che è scritto come $http interceptor
, ma mi piacerebbe fare un ulteriore passo avanti. Quello che mi piacerebbe è che ogni chiamata $http
fallisca (viene rifiutata), qualsiasi consumatore "incatenato" della promessa dovrebbe prima tentare di risolvere l'errore, e se è ANCORA irrisolto (non catturato), ALLORA desidero gestore di errori globali da assumere.Global Error handler che rileva solo promesse "non gestite"
Il caso d'uso è, il mio gestore di errori globale mostra un ringhio "alert box
" nella parte superiore dello schermo. Ma ho un paio di modali che appaiono e gestisco esplicitamente gli errori lì, mostrando un messaggio di errore nella modale stessa. Quindi, in sostanza, questo controllore modale dovrebbe contrassegnare la promessa respinta come "gestita". Ma dal momento che l'intercettatore sembra sempre essere il primo a correre su un $http error
, non riesco a capire un modo per farlo.
Ecco il mio codice intercettore:
angular.module("globalErrors", ['angular-growl', 'ngAnimate'])
.factory("myHttpInterceptor", ['$q', '$log', '$location', '$rootScope', 'growl', 'growlMessages',
function ($q, $log, $location, $rootScope, growl, growlMessages) {
var numLoading = 0;
return {
request: function (config) {
if (config.showLoader !== false) {
numLoading++;
$rootScope.loading = true;
}
return config || $q.when(config)
},
response: function (response) {
if (response.config.showLoader !== false) {
numLoading--;
$rootScope.loading = numLoading > 0;
}
if(growlMessages.getAllMessages().length) { // clear messages on next success XHR
growlMessages.destroyAllMessages();
}
return response || $q.when(response);
},
responseError: function (rejection) {
//$log.debug("error with status " + rejection.status + " and data: " + rejection.data['message']);
numLoading--;
$rootScope.loading = numLoading > 0;
switch (rejection.status) {
case 401:
document.location = "/auth/login";
growl.error("You are not logged in!");
break;
case 403:
growl.error("You don't have the right to do this: " + rejection.data);
break;
case 0:
growl.error("No connection, internet is down?");
break;
default:
if(!rejection.handled) {
if (rejection.data && rejection.data['message']) {
var mes = rejection.data['message'];
if (rejection.data.errors) {
for (var k in rejection.data.errors) {
mes += "<br/>" + rejection.data.errors[k];
}
}
growl.error("" + mes);
} else {
growl.error("There was an unknown error processing your request");
}
}
break;
}
return $q.reject(rejection);
}
};
}]).config(function ($provide, $httpProvider) {
return $httpProvider.interceptors.push('myHttpInterceptor');
})
Questo è il codice di massima di come mi aspetto la chiamata promessa modale per assomigliare:
$http.get('/some/url').then(function(c) {
$uibModalInstance.close(c);
}, function(resp) {
if(resp.data.errors) {
$scope.errors = resp.data.errors;
resp.handled = true;
return resp;
}
});
hai pensato a implementarlo sul lato server, invece? Anche quando dici che dovrebbe * cercare di risolvere *, puoi fare un esempio. – Rajesh
Impossibile farlo sul server, l'intero punto è quello di lavorare con il lato client promesse. Cercando di risolvere, voglio dire che il gestore di errori globale dovrebbe essere l'ultimo catchall per errori in una promessa http. Attualmente è la prima cosa a correre su un errore. –