7

में किसी त्रुटि की स्टैक ट्रेस प्राप्त करना जब मुझे ExtendScript में कोई त्रुटि मिलती है, तो मैं इसके स्टैक ट्रेस को लॉग इन करने में सक्षम होना चाहता हूं। ऐसा प्रतीत होता है कि त्रुटियों में ExtendScript में स्टैक निशान शामिल नहीं हैं, इसलिए मैं त्रुटियों पर स्टैक निशान जोड़ने के विचार के साथ खेल रहा हूं।ExtendScript

स्टैक ट्रेस प्राप्त करने का एकमात्र तरीका मुझे $.stack है। इस क्षेत्र में $.stack में वर्तमान स्टैक ट्रेस शामिल है, जिस समय आप फ़ील्ड तक पहुंचते हैं।

मेरा पहला प्रयास अपनी खुद की त्रुटि ऑब्जेक्ट बनाना था जिसमें ढेर शामिल था। Error ऑब्जेक्ट बहुत खास है जिसमें यह उस कोड की रेखा और फ़ाइल नाम प्राप्त कर सकता है जिसने इसे बनाया है। उदाहरण के लिए,

try { 
    throw new Error("Houston, we have a problem."); 
} 
catch (e) { 
    $.writeln("Line: " + e.line); 
    $.writeln("File: " + e.fileName); 
    $.writeln("Message: " + e.message); 
} 

प्रिंट होगा:

Line: 2 
File: ~/Desktop/Source1.jsx 
Message: Houston, we have a problem. 

मैं इसे इस क्षमता के साथ अपने स्वयं वस्तु बनाने के लिए संभव है नहीं लगता। निकटतम मैं प्राप्त कर सकते हैं यह है:

function MyError(msg, file, line) { 
    this.message = msg; 
    this.fileName = file; 
    this.line = line; 
    this.stack = $.stack; 
} 

try { 
    throw new MyError("Houston, we have a problem.", $.fileName, $.line); 
} 
catch (e) { 
    $.writeln("Line: " + e.line); 
    $.writeln("File: " + e.fileName); 
    $.writeln("Message: " + e.message); 
    $.writeln("Stack: " + e.stack); 
} 

कौन सा प्रिंट:

Line: 9 
File: ~/Desktop/Source2.jsx 
Message: Houston, we have a problem. 
Stack: [Source3.jsx] 
MyError("Houston, we have a p"...,"~/Desktop/Source2.js"...,9) 

यहाँ हम देख सकते हैं कि मैं अपने ही त्रुटि वस्तु बना रहा हूं और स्पष्ट रूप से यह लाइन और फ़ाइल नाम गुजर (MyError के बाद से अपने आप को समझ नहीं सकते हैं)। जब त्रुटि उत्पन्न होती है तो मैंने वर्तमान स्टैक भी शामिल किया है।

यह ठीक काम करता है जब मैं अपनी खुद की त्रुटि ऑब्जेक्ट कहता हूं, लेकिन यह तब काम नहीं करता है जब अन्य कोड नियमित त्रुटि ऑब्जेक्ट को कॉल करते हैं या जब कोई त्रुटि स्वचालित रूप से जेनरेट की जाती है (उदा। अवैध पहुंच से)। मैं किसी भी त्रुटि के स्टैक ट्रेस प्राप्त करने में सक्षम होना चाहता हूं, इससे कोई फर्क नहीं पड़ता कि यह कैसे उत्पन्न होता है।

अन्य दृष्टिकोण Error के कन्स्ट्रक्टर को संशोधित करने के लिए हो सकते हैं, Error प्रोटोटाइप को संशोधित करें, या Error ऑब्जेक्ट को पूरी तरह से बदलें। मैं काम करने के लिए इन दृष्टिकोणों में से कोई भी प्राप्त करने में सक्षम नहीं हूं।

एक और विचार मेरे कोड की प्रत्येक विधि में एक कैच ब्लॉक डालना होगा और वर्तमान स्टैक को त्रुटि में जोड़ना होगा यदि उसके पास पहले से कोई नहीं है। यदि संभव हो तो मैं इस विकल्प से बचना चाहूंगा।

मैं विचारों से बाहर हूं। क्या त्रुटियों के ढेर का पता लगाने का कोई तरीका है?

+0

यदि आपको कुछ काम मिल रहा है तो मुझे वास्तव में दिलचस्पी होगी। मेरी सबसे बड़ी समस्या जैसे ही मैं एक jsxbin प्रारूप में संकलित करता हूं, मुझे त्रुटियों से कुछ भी उपयोगी नहीं मिलता है। मैं लॉगिंग की अविश्वसनीय राशि का मार्ग चला गया हूं, इसलिए मैं उससे डीबग कर सकता हूं। –

+0

व्यक्तिगत रूप से मैं $ .write या $ .writeln निर्देशों का उपयोग नहीं करता। सबसे पहले वे एक्स्टेंडस्क्रिप्ट टूलकिट अपफ्रंट लाएंगे यदि यर खोला नहीं गया है। अगर वास्तव में चेतावनी नहीं दी जाती है तो यह वास्तव में भ्रमित अंत उपयोगकर्ताओं को हो सकता है। इसके अलावा यह वास्तव में वास्तव में धीमी गति से धीमा हो सकता है। मैं डिस्क पर लॉग फाइल लिखना पसंद करता हूं। मेरे पास मेरा खुद का नुस्खा है लेकिन आप इस lib का लाभ उठा सकते हैं: http: //creative-scripts.com/logging-with-a-smile/ – Loic

उत्तर

1

यह सही नहीं है, लेकिन मुझे आंशिक समाधान मिला।

तथ्य 1: Error.prototype एक त्रुटि ऑब्जेक्ट है।

तथ्य 2: जब भी कोई त्रुटि उत्पन्न होती है तो विधि Error.prototype.toString कहा जाता है।

तथ्य 3: फ़ील्ड Error.prototype.toString संशोधित किया जा सकता है।

वह विधि आमतौर पर स्ट्रिंग "त्रुटि" लौटाती है, इसलिए हम इसे अपनी खुद की विधि से बदल सकते हैं जो स्टैक स्टोर करता है और फिर स्ट्रिंग "त्रुटि" देता है।

Error.prototype.toString = function() { 
    if (typeof this.stack === "undefined" || this.stack === null) { 
     this.stack = "placeholder"; 
     // The previous line is needed because the next line may indirectly call this method. 
     this.stack = $.stack; 
    } 
    return "Error"; 
} 

try { 
    throw new Error("Houston, we have a problem."); 
} 
catch (e) { 
    $.writeln("Line: " + e.line); 
    $.writeln("File: " + e.fileName); 
    $.writeln("Message: " + e.message); 
    $.writeln("Stack: " + e.stack); 
} 

परिणाम:

Line: 11 
File: ~/Desktop/Source10.jsx 
Message: Houston, we have a problem. 
Stack: [Source10.jsx] 
toString() 

यह काम करता है! एकमात्र समस्या स्वचालित त्रुटियां है।

Error.prototype.toString = function() { 
    if (typeof this.stack === "undefined" || this.stack === null) { 
     this.stack = "placeholder"; 
     // The previous line is needed because the next line may indirectly call this method. 
     this.stack = $.stack; 
    } 
    return "Error"; 
} 

try { 
    var foo = null; 
    foo.bar; 
} 
catch (e) { 
    $.writeln("Line: " + e.line); 
    $.writeln("File: " + e.fileName); 
    $.writeln("Message: " + e.message); 
    $.writeln("Stack: " + e.stack); 
} 

परिणाम:

Line: 12 
File: ~/Desktop/Source12.jsx 
Message: null is not an object 
Stack: undefined 

तो यह सभी त्रुटियों पर काम नहीं करता है, लेकिन इसकी प्रगति।

2

मैं एक और समाधान के साथ आया हूं, हालांकि इस के लिए आपको अपना कुछ कोड बदलने की आवश्यकता है। इसके बजाय हमेशा की तरह के तरीकों को बुलाने की:

myObject.myMethod1("Hello", "world"); 

आप इस तरह बुला तरीकों को बदलना होगा:

myObject.do("myMethod1", "Hello", "world"); 

यह ऐसे काम करता की एक पूरी उदाहरण है:

Object.prototype.do = function stackHelper() { 
    // Convert the arguments into an array. 
    var argumentArray = Array.prototype.slice.call(arguments); 
    // Remove the first argument, which is the function's name. 
    var functionString = argumentArray.shift(); 
    try { 
     this[functionString].apply(this, argumentArray); 
    } 
    catch (e) { 
     if (typeof e.stack === "undefined" || e.stack === null) { 
      e.stack = $.stack; 
     } 
     throw e; 
    } 
}; 

var myObject = { 
    myMethod1: function myMethod1(myArg1, myArg2){ 
     this.do("myMethod2", myArg1, myArg2); 
    }, 

    myMethod2: function myMethod2(myArg1, myArg2){ 
     this.do("myMethod3", myArg1, myArg2); 
    }, 

    myMethod3: function myMethod3(myArg1, myArg2){ 
     $.writeln(myArg1 + ", " + myArg2 + "!"); 
     var foo = null; 
     foo.bar; // Throws an error. 
    }, 
}; 

try { 
    myObject.do("myMethod1", "Hello", "world"); 
} 
catch (e) { 
    $.writeln("Stack: " + e.stack); 
} 

आउटपुट इस तरह दिखता है:

Hello, world! 
Stack: [do.jsx] 
stackHelper("myMethod1","Hello","world") 
myMethod1("Hello","world") 
stackHelper("myMethod2","Hello","world") 
myMethod2("Hello","world") 
stackHelper("myMethod3","Hello","world") 

यह एक अच्छा समाधान नहीं है, लेकिन कम से कम यह सभी त्रुटियों पर काम करता है।

0

यदि आपको बस एक कस्टम संदेश दिखाना है, तो मैंने यह कोड लिखा था। मुझे लगता है कि हल हो गया है, ... मेरे लिए यह ठीक है।

try 
{ 
    app.selection[0].contents = 1 
} 
catch (myError) 
{ 
    alert(myError.number); // For check the number error 
    if (myError.number == 30477) 
    { 
     alert("Mensagem Edu\n" + "Line: " + myError.line + "\n" + "File: " + myError.fileName + "\n" + "Message: " + myError.message + "\n" + "Stack: " + myError.stack); 
     exit(); 
    } 
    else (myError); 
    {} 
    exit(); 
} 
+0

क्या किसी को 'myError.stack'' के लिए 'अपरिभाषित' से कुछ और मिलता है, जो कि ओपी के सवाल का मुद्दा है? –

1

जहाँ तक मुझे पता के रूप में आप Error.prototype.toString समारोह की [देशी कोड] संशोधित नहीं कर सकते। इसलिए मैं इस समाधान के साथ आया था:

function ReturnCustomErrorString(e, additionalMessage) 
{ 
    try { 
     var errorString = e.toString(); 
     errorString = errorString.concat("\n", "additionalMessage: " + additionalMessage + "\n", "file: " + e.fileName + "\n", "line: " + e.line + "\n", "stack-trace: \n" + $.stack); 
     return errorString; 
    } 
    catch (e) { 
     alert("Error in : " + ReturnCustomErrorString.name + "(...)\n" + e); 
     exit(); 
    } 
} 

उपयोग:

try { 
    // code that does throw an error 
} catch (e) { 
    alert(ReturnCustomErrorString(e)); 
} 

इससे पहले कि मैं इस समारोह मैं अक्सर पकड़ ब्लॉक में कुछ इस तरह से किया था लिखा है:

alert(e); 

अब मैं मैं alert(ReturnCustomErrorString(e)); कर रहा हूं, लेकिन मुझे और अधिक उपयोगी जानकारी मिलती है। तो इस समय मुझे लगता है कि यह समाधान बहुत अच्छा है।