2017-06-20 8 views
5

निम्न कोड चलाते समय, मुझे console.log("fnError: ", fnError) पर टिप्पणी की गई है या नहीं, इसके आधार पर मुझे अलग-अलग परिणाम मिलते हैं। यह मेरे लिए बहुत दूर लगता है।वचन catch और console.log के साथ नोडजेएस बग?

दुनिया में कैसे console.log पर मेरे वादे को प्रभावित करने का आह्वान है?

function run() { 
    var fn = function(){ 
     throw new Error("incorrect message"); 
    }; 

    // returns a promise that should fail with 
    // an error object whose .message is "correct message" 
    var promisifiedFn = function(){ 
     return Promise.resolve() 
      .then(fn) 
      .catch((fnError) => { 
       // commenting this out fixes things! // 
       console.log("fnError: ", fnError); 
       /////////////////////////////////////// 

       fnError.message = "correct message"; 
       throw fnError; 
      }) 
    } 

    promisifiedFn().catch((e) => { 
     console.log("caught error.message:", e.message); 
     console.log("caught error:", e); 
    }); 
} 
run(); 

ऊपर का उत्पादन:

// fnError: Error: incorrect message 
//  at fn (/Users/sam/dev/ethereum/pennyeth/js/temp.js:18:9) 
//  at <anonymous> 
//  at process._tickCallback (internal/process/next_tick.js:169:7) 
//  ... 
// caught error.message: correct message 
// caught error: Error: incorrect message 
//  at fn (/Users/sam/dev/ethereum/pennyeth/js/temp.js:18:9) 
//  at <anonymous> 
//  at process._tickCallback (internal/process/next_tick.js:169:7) 
//  ... 

सूचना "गलत संदेश" लॉग इन किया जा रहा है। और अगर आप बाहर टिप्पणी console.log("fnError: ", fnError) आप इस मिल:

// caught error.message: correct message 
// caught error: Error: correct message 
//  at fn (/Users/sam/dev/ethereum/pennyeth/js/temp.js:18:9) 
//  at <anonymous> 
//  at process._tickCallback (internal/process/next_tick.js:169:7) 
//  .... 

नोड 8.0.0

+0

नोट: मेरे वास्तविक एप्लिकेशन कोड में, मैं इसे पुनर्स्थापित करने से पहले त्रुटि को लॉग इन नहीं कर रहा हूं, और मुझे अभी भी यह व्यवहार मिलता है। दुर्भाग्य से मैं इसका एक न्यूनतम उदाहरण समझने में सक्षम नहीं हूं। –

+0

यह विचित्र है। मैंने इसे क्रोम 59 की कोशिश की और इसमें एक ही समस्या नहीं है। लेकिन नोड 7.9.0, नोड 8.0.0, और नोड 8.1.2 सभी में यह व्यवहार (या बग) है। – styfle

+1

मेरा एकमात्र विचार यह है कि console.log stdout को प्रस्तुत करने से पहले त्रुटि ऑब्जेक्ट को कैशिंग कर रहा है। ध्यान दें कि "गलत संदेश" दोनों परिणाम एक ही ऑब्जेक्ट को लॉग कर रहे हैं। – styfle

उत्तर

2

यह व्यवहार की उम्मीद है।

त्रुटि लॉगिंग (जो कम से कम util.inspect या String से गुजरती है) इसकी .stack संपत्ति का मूल्यांकन करती है। स्टैक स्ट्रिंग प्रारंभ नहीं होती है जब त्रुटि ऑब्जेक्ट को तत्काल किया जाता है, लेकिन स्मृति को सहेजने के लिए आलसी बनाया गया है।स्टैक ट्रेस में त्रुटि का संदेश शामिल होगा, और जब आप .message संपत्ति को बदलते हैं तो यह स्टैक ट्रेस में दिखाई देगा या नहीं, इस पर निर्भर करता है कि यह पहले से ही बनाया गया था या नहीं।

the V8 stack trace API description से:

दक्षता स्टैक ट्रेस के लिए स्वरूपित नहीं कर रहे हैं जब वे पर कब्जा कर लिया जाता है, लेकिन मांग पर पहली बार ढेर संपत्ति पहुँचा जा सकता है।

और the official node Error documentation से:

स्ट्रिंग स्टैक ट्रेस का प्रतिनिधित्व lazily उत्पन्न होती है जब error.stack संपत्ति है पहुँचा।

+0

क्रोम के पास Node.js से अलग व्यवहार क्यों है? क्या यह अनुकूलन और क्रोम बनाने वाला नोड नहीं है? – styfle

+0

@styfle मैंने अभी तक यह कोशिश नहीं की है, लेकिन मुझे संदेह है कि अंतर केवल 'console.log' में है और' error.stack' – Bergi

+1

@styfle मैं स्पष्ट रूप से '.stack' तक पहुंचने पर क्रोम में पुन: उत्पन्न कर सकता हूं। लेकिन वास्तव में, 'console.log (e)' अकेले अद्यतन संदेश दिखाता है। – Bergi

1

मैं नीचे केवल 4 लाइनों के साथ इस "बग" पुन: पेश करने में सक्षम था चल रहा है।

var e = new Error('first'); 
console.log(e); 
e.message = 'new'; 
console.log(e); 

मैंने इसे क्रोम 59 की कोशिश की और इसमें एक ही समस्या नहीं है।

हालांकि नोड 7.9.0, नोड 8.0.0, और नोड 8.1.2 सभी को यह समस्या है।

मैंने गिटहब #13832 पर एक बग के रूप में रिपोर्ट की ताकि हम देखेंगे कि इसमें क्या आता है।

अद्यतन 1: यह एक समय मुद्दा नहीं है दिखाने के लिए, हम setTimeout कॉल

var e = new Error('first'); 
console.log(e); 
setTimeout(() => { e.message = 'new'; }, 1000); 
setTimeout(() => console.log(e), 2000); 

समस्या बनी रहती है भले ही हम console.log() जो मुझे विश्वास है उत्पादन कैश किया गया है बनाता है कॉल करने के लिए इंतजार जोड़ सकते हैं।

अद्यतन 2: मैं MSCDEX GitHub पर से एक प्रतिक्रिया मिल गया:

यह आशा की जाती है क्योंकि आप जो देख रहे स्टैक ट्रेस, एक बार यह उत्पन्न जो त्रुटि संदेश भी शामिल है। स्टैक ट्रेस आलसी उत्पन्न होता है और केवल एक बार (प्रदर्शन कारणों से), इसलिए आप दोनों बार एक ही आउटपुट देखते हैं।

यदि आप आउटपुट e.message में अपना कोड बदलते हैं, तो आप आउटपुट में अपेक्षित परिवर्तन देखेंगे।

अंत में, दोनों MSCDEX और Bergi कह रहे हैं मूल कारण आलसी मूल्यांकन है।

आप जो कर रहे हैं वह शायद एक आम परिदृश्य नहीं है, इसलिए मैं भविष्य में ऐसा करने से बचूंगा क्योंकि यह प्रकट नहीं होता है क्योंकि node.js टीम इस व्यवहार को बदल देगी।

+0

मुझे अभी भी यह समस्या मेरे एप्लिकेशन कोड में मिल रही है, जो कुछ समान है लेकिन 'console.log' नहीं करता है , जिसका अर्थ है कि मुझे "पुराना" त्रुटि संदेश मिलता है। –

संबंधित मुद्दे