Angular 1.6.0 : "아마도 처리되지 않은 거부"오류
이 질문에 이미 답변이 있습니다.
Angular 1.6.0까지 우리에게 도움이 된 Angular 앱에는 약속을 해결하는 패턴이 있습니다.
resource.get().$promise
.then(function (response) {
// do something with the response
}, function (error) {
// pass the error the the error service
return errorService.handleError(error);
});
Karma에서 오류를 발생시키는 방법은 다음과 같습니다.
resourceMock.get = function () {
var deferred = $q.defer();
deferred.reject(error);
return { $promise: deferred.promise };
};
이제 1.6.0으로 업데이트하면서 Angular는 "Possibly unhandled rejection"오류와 함께 거부 된 약속에 대해 단위 테스트 (Karma)에서 갑자기 불평하고 있습니다. 그러나 우리는 오류 서비스를 호출하는 두 번째 함수에서 거부를 처리하고 있습니다.
Angular가 정확히 무엇을 찾고 있습니까? 거부를 "처리"하는 방법은 무엇입니까?
이 코드를 구성에 추가해보십시오. 한 번 비슷한 문제가 있었는데이 해결 방법이 트릭을 수행했습니다.
app.config(['$qProvider', function ($qProvider) {
$qProvider.errorOnUnhandledRejections(false);
}]);
표시되는 코드는를 호출하기 전에 발생하는 거부를 처리합니다 .then
. 이러한 상황에서는 전달한 두 번째 콜백이 .then
호출되고 거부가 처리됩니다.
그러나 호출 한 promise .then
가 성공하면 첫 번째 콜백을 호출합니다. 이 콜백이 예외를 던지거나 거부 된 약속을 반환하는 경우 두 번째 콜백이 첫 번째 원인에 의한 거부를 처리하지 않기 때문에이 결과로 인한 거부는 처리 되지 않습니다. 이것이 Promises / A + 사양을 준수하는 promise 구현이 작동하고 Angular promise가 준수하는 방식입니다.
다음 코드로이를 설명 할 수 있습니다.
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")));
Promises / A +를 준수하는 Node에서 실행하면 다음을 얻을 수 있습니다.
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
Found the issue by rolling back to Angular 1.5.9 and rerunning the test. It was a simple injection issue but Angular 1.6.0 superseded this by throwing the "Possibly Unhandled Rejection" error instead, obfuscating the actual error.
The first option is simply to hide an error with disabling it by configuring errorOnUnhandledRejections
in $qProvider configuration as suggested Cengkuru Michael
BUT this will only switch off logging. The error itself will remain
The better solution in this case will be - handling a rejection with .catch(fn)
method:
resource.get().$promise
.then(function (response) {})
.catch(function (err) {});
LINKS:
- Promise
- Angular:
To avoid having to type additional .catch(function () {})
in your code in multiple places, you could add a decorator
to the $exceptionHandler
.
This is a more verbose option than the others but you only have to make the change in one place.
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);
};
}
};
Please check the answer here:
Possibly unhandled rejection in Angular 1.6
This has been fixed with 316f60f and the fix is included in the v1.6.1 release.
You could mask the problem by turning off errorOnUnhandledRejections, but the error says you're needing to "handle a possible rejection" so you just need to add a catch to your promise.
resource.get().$promise
.then(function (response) {
// do something with the response
}).catch(function (error)) {
// pass the error to the error service
return errorService.handleError(error);
});
Reference: https://github.com/angular-ui/ui-router/issues/2889
I have observed the same behavior during test execution. It is strange that on production code works fine and fails only on tests.
Easy solution to make your tests happy is to add catch(angular.noop)
to your promise mock. In case of example above it should looks like this:
resourceMock.get = function () {
var deferred = $q.defer();
deferred.reject(error);
return { $promise: deferred.promise.catch(angular.noop) };
};
I was also facing the same issue after updating to Angular 1.6.7 but when I looked into the code, error was thrown for $interval.cancel(interval);
for my case
My issue got resolved once I updated angular-mocks
to latest version(1.7.0).
It may not be your speficic situation, but I had a similar problem.
In my case, I was using angular-i18n, and getting the locale dictionary asynchronously. The problem was that the json file it was getting was incorrectly indented (mixing spaces and tabs). The GET request didn't failed.
Correcting the indentation solved the problem.
I had this same notice appear after making some changes. It turned out to be because I had changed between a single $http
request to multiple requests using angularjs $q
service.
I hadn't wrapped them in an array. e.g.
$q.all(request1, request2).then(...)
rather than
$q.all([request1, request2]).then(...)
I hope this might save somebody some time.
참고URL : https://stackoverflow.com/questions/41063947/angular-1-6-0-possibly-unhandled-rejection-error
'code' 카테고리의 다른 글
col-md-1.5를 부트 스트랩에 줄 수 있습니까? (0) | 2020.11.14 |
---|---|
Ansible : 명령의 stdout을 새 변수에 저장 하시겠습니까? (0) | 2020.11.14 |
메서드가 'void'를 반환하는지 반영하여 확인하는 방법 (0) | 2020.11.14 |
달력에 대한 날짜 개체 [자바] (0) | 2020.11.14 |
실수로 푸시 된 커밋 : git 커밋 메시지 변경 (0) | 2020.11.14 |