Angulaire 1.6.0: erreur de "rejet éventuellement non manipulé" [dupliquer]

cette question a déjà une réponse ici:

nous avons un modèle pour résoudre des promesses dans notre application angulaire qui nous a bien servi Jusqu'à Angular 1.6.0:

    resource.get().$promise
        .then(function (response) {
        // do something with the response
        }, function (error) {
            // pass the error the the error service
            return errorService.handleError(error);
        });

Et voici comment nous déclenchons l'erreur dans Karma:

    resourceMock.get = function () {
        var deferred = $q.defer();
        deferred.reject(error);
        return { $promise: deferred.promise };
    };

maintenant, avec la mise à jour à 1.6.0, Angular se plaint soudainement dans nos tests unitaires (en Karma) pour des promesses rejetées avec une erreur de" rejet éventuellement non manipulé". Mais nous gérons le rejet dans la deuxième fonction qui appelle notre service d'erreur.

que cherche exactement Angular ici? Comment veut-il qu'on" gère " le rejet?

59
demandé sur Mistalis 2016-12-09 18:38:55

11 réponses

essayez d'ajouter ce code à votre configuration. J'ai eu un problème similaire une fois, et cette solution a fait l'affaire.

app.config(['$qProvider', function ($qProvider) {
    $qProvider.errorOnUnhandledRejections(false);
}]);
62
répondu Cengkuru Michael 2017-12-15 02:11:28

le code que vous affichez traitera un rejet qui se produit avant l'appel à .then . Dans une telle situation, le 2ème rappel que vous passez à .then sera appelé, et le rejet seront traitées.

cependant , lorsque la promesse sur laquelle vous appelez .then est réussie, il appelle le premier rappel. si ce callback lance une exception ou renvoie une promesse rejetée, ce rejet résultant ne sera pas traité , parce que le 2e rappel ne gère pas les rejets en cause au 1er. C'est exactement comme cela que les implémentations de promesse conformes au travail de spécification Promises/a+ et les promesses angulaires sont conformes.

vous pouvez l'illustrer avec le code suivant:

function handle(p) {
    p.then(
        () => {
            // This is never caught.
            throw new Error("bar");
        },
        (err) => {
            console.log("rejected with", err);
        });
}

handle(Promise.resolve(1));
// We do catch this rejection.
handle(Promise.reject(new Error("foo")));

si vous l'exécutez dans Node, qui est aussi conforme à Promises / a+, vous obtenez:

rejected with Error: foo
    at Object.<anonymous> (/tmp/t10/test.js:12:23)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3
(node:17426) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: bar
19
répondu Louis 2016-12-09 16:39:15

a trouvé le problème en retournant à L'angle 1.5.9 et en relançant l'essai. Il s'agissait d'une simple question d'injection, mais le point 1.6.0 anguleux a remplacé cette erreur par une erreur de rejet "possiblement Non manipulé", ce qui a masqué l'erreur réelle.

18
répondu Groucho 2016-12-12 16:08:12

la première option consiste simplement à masquer une erreur en la désactivant en configurant errorOnUnhandledRejections dans la configuration $qProvider comme suggéré Cengkuru Michael

mais cela n'éteindra que la journalisation. L'erreur elle-même restera

la meilleure solution dans ce cas sera - traitement d'un rejet avec .catch(fn) méthode:

resource.get().$promise
    .then(function (response) {})
    .catch(function (err) {});

LINKS:

15
répondu Andrii Verbytskyi 2017-09-19 06:49:40

s'il vous Plaît vérifier la réponse ici:

rejet possiblement non freiné dans L'angle 1,6

cette valeur a été fixée à 316f60f et le correctif est inclus dans le v1.6.1 release .

3
répondu Piotr Pradzynski 2018-02-05 12:58:38

j'ai observé le même comportement pendant l'exécution du test. Il est étrange que sur le code de production fonctionne bien et échoue seulement sur les tests.

la solution facile pour rendre vos tests heureux est d'ajouter catch(angular.noop) à votre mock promesse. Dans le cas de l'exemple ci-dessus, il devrait ressembler à ceci:

resourceMock.get = function () {
    var deferred = $q.defer();
    deferred.reject(error);
    return { $promise: deferred.promise.catch(angular.noop) };
};
2
répondu Valdermeyder Hussar 2016-12-15 10:06:48

vous pouvez masquer le problème en désactivant les rejets erroronunhandled, mais l'erreur dit que vous avez besoin de" gérer un rejet possible " donc vous avez juste besoin d'ajouter une prise à votre promesse.

resource.get().$promise
    .then(function (response) {
    // do something with the response
    }).catch(function (error)) {
        // pass the error the the error service
        return errorService.handleError(error);
    });

référence: https://github.com/angular-ui/ui-router/issues/2889

2
répondu giselleghadyani 2017-05-16 18:32:21

j'étais également face à la même question après la mise à jour à L'angle 1.6.7 mais quand j'ai regardé dans le code, erreur a été jeté pour $interval.cancel(interval); pour mon cas

mon problème a été résolu une fois que j'ai mis à jour angular-mocks à la dernière version(1.7.0).

2
répondu Dilip 2018-06-04 16:21:52

pour éviter d'avoir à taper .catch(function () {}) dans votre code à plusieurs endroits, vous pouvez ajouter un decorator au $exceptionHandler .

C'est une option verbose que les autres, mais vous n'avez qu'à faire le changement dans un seul endroit.

angular
    .module('app')
    .config(configDecorators);

configDecorators.$inject = ["$provide"];
function configDecorators($provide) {

    $provide.decorator("$exceptionHandler", exceptionHandler);

    exceptionHandler.$inject = ['$delegate', '$injector'];
    function exceptionHandler($delegate, $injector) {
        return function (exception, cause) {

            if ((exception.toString().toLowerCase()).includes("Possibly unhandled rejection".toLowerCase())) {
                console.log(exception); /* optional to log the "Possibly unhandled rejection" */
                return;
            }
            $delegate(exception, cause);
        };
    }
};
1
répondu Urielzen 2018-05-27 22:05:08

ce n'est peut-être pas votre situation particulière, mais j'ai eu un problème similaire.

dans mon cas, j'utilisais angular-i18n, et j'obtenais le dictionnaire local de façon asynchrone. Le problème était que le fichier json qu'il recevait était incorrectement indenté (mélange des espaces et des onglets). La requête de L'EEG n'a pas échoué.

Correction de l'indentation résolu le problème.

0
répondu monstercode 2018-01-29 13:45:41

j'ai eu ce même avis apparaître après avoir fait quelques changements. Il s'est avéré que c'était parce que j'avais changé entre une seule requête $http et plusieurs requêtes utilisant le service $q d'angularjs.

Je ne les avais pas enveloppés dans un tableau. par exemple

$q.all(request1, request2).then(...) 

plutôt que

$q.all([request1, request2]).then(...)

j'espère que cela pourrait sauver quelqu'un un certain temps.

0
répondu JamesEddyEdwards 2018-07-24 22:59:24