javascript - कोणीय 1.6.0: "संभवतः अस्वीकार की गई अस्वीकृति" त्रुटि




angularjs karma-runner (8)

आप errorOnUnhandledRejections को बंद करके समस्या का सामना कर सकते हैं, लेकिन त्रुटि कहती है कि आपको "एक संभावित अस्वीकृति को संभालने" की आवश्यकता है ताकि आपको अपने वादे पर एक पकड़ जोड़ने की आवश्यकता हो।

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);
    });

संदर्भ: https://github.com/angular-ui/ui-router/issues/2889

इस सवाल का पहले से ही यहाँ एक जवाब है:

हमारे पास हमारे कोणीय ऐप में वादों को हल करने के लिए एक पैटर्न है, जिसने हमें कोणीय 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);
        });

और यहाँ हम कर्म में त्रुटि को कैसे ट्रिगर कर रहे हैं:

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

अब, 1.6.0 के अद्यतन के साथ, कोणीय हमारे इकाई परीक्षणों (कर्म में) को अस्वीकार कर दिया गया है "अस्वीकार्य अस्वीकृति" के साथ वादे के लिए। लेकिन हम दूसरे फ़ंक्शन में अस्वीकृति को संभाल रहे हैं जो हमारी त्रुटि सेवा को कॉल करता है।

वास्तव में कोणीय यहाँ क्या देख रहा है? यह कैसे हमें अस्वीकृति को "हैंडल" करना चाहता है?


आपके द्वारा दिखाया गया कोड उस कॉल को .then से पहले होने वाली अस्वीकृति को हैंडल करेगा। ऐसी स्थिति में, आप जिस दूसरी कॉलबैक को पास करते .then , उसे कॉल किया जाएगा, और अस्वीकृति को संभाल लिया जाएगा।

हालाँकि , जब आप जिस वादे पर कॉल करते .then वह सफल होता है, यह 1 कॉलबैक कहता है। यदि यह कॉलबैक एक अपवाद फेंकता है या अस्वीकार किए गए वादे को वापस करता है, तो इसके परिणामस्वरूप अस्वीकृति को नियंत्रित नहीं किया जाएगा , क्योंकि 2 कॉलबैक 1 के कारण अस्वीकार को नहीं संभालता है। यह Promises/A+ विनिर्देशन कार्य के अनुरूप कार्यान्वयन का वादा कैसे करता है, और कोणीय वादे अनुपालन योग्य हैं।

आप निम्नलिखित कोड के साथ इसका वर्णन कर सकते हैं:

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")));

यदि आप इसे नोड में चलाते हैं, जो वादे / ए + के अनुरूप है, तो आपको मिलता है:

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

कई स्थानों पर अपने कोड में अतिरिक्त .catch(function () {}) टाइप करने से बचने के लिए, आप $exceptionHandler .catch(function () {}) में decorator जोड़ सकते हैं।

यह दूसरों की तुलना में अधिक क्रियाशील विकल्प है लेकिन आपको केवल एक ही स्थान पर बदलाव करना होगा।

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);
        };
    }
};

कुछ बदलाव करने के बाद मुझे यही नोटिस दिखाई दिया। यह इसलिए निकला क्योंकि मैं angularjs $q सेवा का उपयोग करते हुए एक ही $http अनुरोध से कई अनुरोधों के बीच बदल गया था।

मैंने उन्हें एक सरणी में नहीं लपेटा था। जैसे

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

बजाय

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

मुझे आशा है कि यह किसी को कुछ समय बचा सकता है।


कोणीय 1.5.9 पर वापस रोल करके और परीक्षण को पुन: निर्देशित करके समस्या मिली। यह एक साधारण इंजेक्शन मुद्दा था, लेकिन एंगुलर 1.6.0 ने इसके बजाय "पॉसिबल अनहैंड्ड रिजेक्शन" त्रुटि को फेंक दिया, वास्तविक त्रुटि को मानने से चूक कर दिया।


पहला विकल्प केवल त्रुटि को छिपाने के साथ एक त्रुटि को छिपाने के लिए है।

लेकिन यह केवल लॉगिंग को बंद कर देगा। त्रुटि स्वयं रहेगी

इस मामले में बेहतर समाधान होगा - .catch(fn) विधि के साथ अस्वीकृति को .catch(fn) :

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

कड़ियाँ:


मैंने परीक्षण निष्पादन के दौरान समान व्यवहार देखा है। यह अजीब है कि उत्पादन कोड ठीक काम करता है और केवल परीक्षणों पर विफल रहता है।

अपने परीक्षणों को खुश करने के लिए आसान उपाय यह है कि आप अपने वादे के catch(angular.noop) जोड़ें। ऊपर के उदाहरण के मामले में यह इस तरह दिखना चाहिए:

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


यह आपकी स्थानिक स्थिति नहीं हो सकती है, लेकिन मुझे एक समान समस्या थी।

मेरे मामले में, मैं कोणीय- i18n का उपयोग कर रहा था, और स्थानीय रूप से अतुल्यकालिक शब्दकोश प्राप्त कर रहा था। समस्या यह थी कि जो json फाइल मिल रही थी वह गलत तरीके से इंडेंट की हुई थी (रिक्त स्थान और टैब को मिलाना)। GET अनुरोध विफल नहीं हुआ।

इंडेंटेशन ठीक करने से समस्या हल हो गई।





angularjs-1.6