2009-02-11 15 views
53

Grails अपने लंबे ढेर डंप के साथ डीबग करने के लिए एक भालू का थोड़ा सा हो सकता है। समस्या का स्रोत प्राप्त करना मुश्किल हो सकता है। मुझे BootStrap.groovy में कुछ बार जला दिया गया है "def foo = new foo (a: a, b: b) .save()" उदाहरण के लिए। Grails ऐप्स डीबग करने के लिए आपकी पसंदीदा चाल क्या हैं?आपकी पसंदीदा Grails डीबगिंग चाल क्या हैं?

+2

बेस्ट सवाल ... –

+1

@MichaelEaster seconded। यह वास्तव में एक शर्म की बात है कि SO इन प्रकार के केबी लेखों को रचनात्मक नहीं मानते हैं। वे उतने ही रचनात्मक होते हैं जितना वे आते हैं और उत्तर मतदान प्रणाली एक विकी-शैली केबी के मुकाबले अधिक से कम उपयोगी से युक्तियों को सामूहिक रूप से क्रमबद्ध करने के लिए एक उत्कृष्ट प्रणाली प्रदान करती है। – Tobia

उत्तर

32

कुछ सामान्य टिप्स:

  • साफ़ stacktrace.log, grails रन एप्लिकेशन है, तो खुला स्टैकट्रेस एक दर्शक में लॉग इन करें (मैं लिनक्स पर less stacktrace.log पसंद करता हूं) ... एक बार आपके दर्शक में, .groovy और .gsp ... के लिए खोजें जो आमतौर पर आपको उस चीज़ पर लाता है जिसे आप वास्तव में देखते हैं।
  • एक स्टैकट्रेस एक जीएसपी फ़ाइल में एक पंक्ति संख्या दर्शाता है, तो आप क्वेरी स्ट्रिंग में ?showSource, यानी http://localhost:8080/myProject/myController/myAction?showSource के साथ एक ब्राउज़र में दृश्य खोलने चाहिए ... इस संकलित जीएसपी स्रोत है, और सभी जीएसपी लाइन नंबर से पता चलता स्टैकट्रैक संकलित जीएसपी का संदर्भ देता है, वास्तविक जीएसपी स्रोत
  • हमेशा, हमेशा, कम से कम कुछ न्यूनतम त्रुटि हैंडलिंग के साथ हमेशा बचाता है।

उदाहरण:

try { 
    if(!someDomainObject.save()) { 
     throw new Exception ("Save failed") 
    } 
} catch(Exception e) { 
    println e.toString() 
    // This will at least tell you what is wrong with 
    // the instance you are trying to save 
    someDomainObject.errors.allErrors.each {error -> 
     println error.toString() 
    } 
} 

इसके अलावा, यह बहुत बस stacktraces और त्रुटि संदेश को पहचानने के लिए नीचे आता है ... बहुत समय, Grails त्रुटि संदेश यह देता में अविश्वसनीय रूप से बेकार है आप, लेकिन आप पैटर्न पहचान करने के लिए, की तरह सीख सकते हैं निम्नलिखित:

  • सबसे मुश्किल त्रुटियों में से कुछ की समझ बनाने के लिए कर रहे हैं क्योंकि आप grails clean या grails upgrade ... इन जनसंपर्क से बचने के लिए नहीं चला oblems, मैं हमेशा grails चलाने के लिए कमांड लाइन पर निम्नलिखित का उपयोग करता हूं: grails clean; yes | grails upgrade; grails run-app
  • यदि त्रुटि को कक्षा की डुप्लिकेट परिभाषाओं के साथ करना है, तो सुनिश्चित करें कि आप उस वर्ग को घोषित करते हैं जो वर्ग कक्षा के शीर्ष पर है फ़ाइल
  • यदि त्रुटि स्कीमा मेटाडेटा, कनेक्शन, सॉकेट या उसके जैसा कुछ भी है, तो सुनिश्चित करें कि आपका डेटाबेस कनेक्टर lib/ में है, सुनिश्चित करें कि DataSource.groovy और उपयोगकर्ता नाम, पासवर्ड के लिए डेटाबेस में आपकी अनुमतियां सही हैं , और मेजबान, और सुनिश्चित करें कि आप अपने कनेक्टर के संस्करण के इन्स और आउट (यानी mysql संबंधक संस्करण 5.1.x उपनाम है कि आप DataSource.groovy में यूआरएल पर useOldAliasMetadataBehavior=true स्थापित करने के लिए आवश्यकता हो सकती है के साथ एक अजीब मुद्दा)

और इसी तरह की है। पहचानने के लिए सीखने के लिए बहुत सारे पैटर्न हैं।

+0

"टी/myController/myAction? ShowSource" क्या यह उत्पादन मोड में काम करता है? :) – itsraja

+0

क्षमा करें नाप - केवल विकास मोड, परीक्षण या उत्पादन नहीं –

+1

मुझे कभी नहीं पता था कि क्यों सहेजना नहीं होगा डिफ़ॉल्ट रूप से त्रुटि - मुझे लगता है कि यह हर डेवलपर के लिए एक पूरी तरह से अप्रत्याशित व्यवहार है, इसलिए मैं ' grails.gorm.failOnError = true 'पहली चीज़ जब एक नई परियोजना शुरू करते हैं। – elias

16
  • क्रिस राजा के सुझाव को जोड़ने के लिए, पर बचाने के लिए, मैं एक पुन: प्रयोज्य बंद लिखा है:

    Closure saveClosure = { domainObj -> 
         if(domainObj.save()) 
          println "Domain Object $domainObj Saved" 
         else 
         { 
           println "Errors Found During Save of $domainObj!" 
           println domainObj.errors.allErrors.each { 
            println it.defaultMessage 
           } 
         } 
        } 
    

तो फिर तुम बस इसे हर जगह उपयोग कर सकते हैं और यह त्रुटि रिपोर्टिंग का ख्याल रखेंगे:

def book = new Book(authorName:"Mark Twain") 
    saveClosure(book) 
  • साथ ही, मैंका उपयोग- यह अतिरिक्त लॉगिंग की अनुमति देता है, और मैंने अपने मुख्य के नीचे टैग जोड़ा - जो मुझे सत्र/अनुरोध में सभी चरों का एक दृश्य देता है।

  • Runtime Logging plugin रनटाइम पर लॉगिंग सक्षम करने की अनुमति देता है।

  • इस उत्तर को लिखते समय, P6SPY plugin ऐसा लगता है कि यह उपयोगी हो सकता है - यह आपके ऐप को प्रॉक्सी के रूप में कार्य करके डेटाबेस के विरुद्ध किए गए सभी बयान लॉग करता है।

  • Grails कंसोल भी उपयोगी है। मैं इसे इंटरैक्टिव रूप से चार कोड के साथ पोक करने और प्रयोग करने के लिए उपयोग करता हूं, जो डिबगिंग के दौरान काम में आता है।

  • और निश्चित रूप से, डीबगर के माध्यम से कदम उठाने में सक्षम होना मीठा है। मैंने IntelliJ IDEA पर स्विच किया क्योंकि इसमें सबसे अच्छा Grails/Groovy समर्थन है।

+2

saveClosure (x) वास्तव में उस groovy है? निश्चित रूप से यह सहेजने() विधि को ओवरराइड करने के लिए अच्छा होगा? – Armand

+3

अब और अधिक p6spy से परेशान मत करो। वसंत अंतर्दृष्टि का प्रयोग करें। कॉन्फ़िगरेशन समस्याओं के बिना इसमें p6spy की सभी कार्यक्षमताएं हैं। इसके अलावा आप इसे प्रदर्शन ट्यूनिंग के लिए उपयोग कर सकते हैं। पीटर लेडब्रुक के वीडियो देखें। http://www.youtube.com/watch?v=rR-8EMKzduA – JGFMK

1

सरल अनुप्रयोगों के लिए मैं उपयोग println statement.It करना बहुत आसान trick.For जटिल अनुप्रयोगों विचार IntelliJ में डिबग मोड का उपयोग करें।

14

मैंने एक बार एक अनुभवी ग्रोवी डेवलपर से पूछा कि वह अपने अनुप्रयोगों को प्रभावी ढंग से कैसे डिबग किया गया है। उनका जवाब:

मैं परीक्षण लिखता हूं!

और उसके पास एक बहुत अच्छा बिंदु है: यदि आपके कोड में पर्याप्त इकाई और एकीकरण परीक्षण है, तो आपको शायद ही कभी कुछ भी डीबग करने की आवश्यकता होगी।

+3

मुझे खुशी है कि आखिर में एक चांदी की बुलेट है। –

+14

डब्ल्यूटीएफ? तो जब उनके परीक्षण विफल हो गए तो उन्होंने कोड को कैसे डीबग किया? या क्या उसका कोड कभी भी अपने परीक्षणों में असफल रहा? किस मामले में वह केवल वह परीक्षण कर रहा था जिसे वह जानता था कि काम करेगा? यह कहना बहुत अजीब बात है और मुझे tautological के रूप में हमला करता है। जैसा कि आप सही कहें तो स्मग का उल्लेख न करें। – Simon

+0

परीक्षण लिखने के लिए साइमन और डब्ल्यूटीएफ प्रतिक्रिया ... आप अपने परीक्षणों में लॉगिंग जोड़ने का प्रयास कर सकते हैं। – JGFMK

4

मैं: इसके अलावा आप अपने साथी डेवलपर्स के लिए इस तरह आत्मसंतुष्ट बातें कहने के लिए मिलता है ...

Grails के लिए मुझे यकीन नहीं है कि यह बॉक्स के बाहर किया जा सकता है, लेकिन वेबपैप्स में मुझे यह पता लगाना उपयोगी है कि "मैं कौन हूं?" विभिन्न दृश्य फ़ाइलों में सुविधा।

विचार खंडित एचटीएमएल में एक संदेश को उत्सर्जित करने के लिए उत्सर्जित करना है। यह विशेष रूप से सच है जब मैं पहली बार एक ऐप का सामना कर रहा हूं।

Grails में, मैं इसे एक कस्टम टैग के साथ करता हूं। उदाहरण के लिए, सूची पर विचार करें।एक छात्र के लिए जीएसपी:

<g:debug msg="student list" /> 

यहाँ कोड है:

class MiscTagLib { 
    def debug = { map -> 
     if (grailsApplication.config.grails.views.debug.mode == true) { 
      def msg = map['msg'] 
      out << "<h2>${msg}</h2><br/>" 
     } 
    } 
} 

महत्वपूर्ण यह है कि आप उन टैग वहाँ में, अगर वांछित, छोड़ सकते हैं के रूप में वे केवल जब मोड में सक्षम किया गया है में दिखाई देते हैं Config.groovy:

grails.views.debug.mode=true 
7

GrailsUtil के साथ अपवाद लॉग करने के लिए।

try{ 
    ... 
}catch (Exception e){ 
    log.error("some message", GrailsUtil.sanitize(e)) 
    ... 
} 

More info about sanitize.

4

स्रोत कोड को देखते हुए! इसने मुझे कई बार बचा लिया है! और अब यह कोड गिटहब में होस्ट किया गया है, यह पहले से कहीं अधिक आसान है। बस "टी" दबाएं और जिस वर्ग को आप ढूंढ रहे हैं उसे ढूंढने के लिए टाइप करना शुरू करें!

http://github.com/grails/grails-core

5

Bootsrap.groovy करने के लिए इस कोड को जोड़ने: init विधि को बचाने के ऊपर लिख और साथ ही कुछ अन्य कोड निष्पादित, इस मामले में त्रुटि संदेश को प्रिंट होगा।

class BootStrap { 

    def grailsApplication 

    def init = {servletContext -> 

     grailsApplication.domainClasses.each { clazz -> 
      clazz.clazz.get(-1) 

      def gormSave = clazz.metaClass.getMetaMethod('save') 

      clazz.metaClass.save = {-> 

       def savedInstance = gormSave.invoke(delegate) 
       if (!savedInstance) { 
        delegate.errors.each { 
         println it 
        } 
       } 
       savedInstance 
      } 

      def gormSaveMap = clazz.metaClass.getMetaMethod('save', Map) 
      clazz.metaClass.save = { Map m -> 
       def savedInstance = gormSaveMap.invoke(delegate, m) 
       if (!savedInstance) { 
        delegate.errors.each { 
         println it 
        } 
       } 
       savedInstance 

      } 

      def gormSaveBoolean = clazz.metaClass.getMetaMethod('save', Boolean) 
      clazz.metaClass.save = { Boolean b -> 
       def savedInstance = gormSaveBoolean.invoke(delegate, b) 
       if (!savedInstance) { 
        delegate.errors.each { 
         println it 
        } 
       } 
       savedInstance 


      } 
     } 
... 
} 

आशा व्यक्त की कि मदद करता है किसी को :)

(मुझे पता है इसके वास्तव में सूखी नहीं)

रेफरी: हाल की स्मृति में http://grails.1312388.n4.nabble.com/How-to-override-save-method-on-domain-class-td3021424.html

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