Jakie są Twoje ulubione triki debugowania Grails? [zamknięte]

Grails może być trochę Niedźwiedziem do debugowania za pomocą długich zrzutów stosu. Dotarcie do źródła problemu może być trudne. Poparzyłem się kilka razy w butach.groovy robi " def foo = new Foo (a: a, b: b).save()", na przykład. Jakie są Twoje ulubione sztuczki do debugowania aplikacji Grails?

Author: An̲̳̳drew, 2009-02-11

9 answers

Kilka ogólnych wskazówek:

  • Wyczyść stacktrace.Zaloguj się, Uruchom aplikację grails, a następnie otwórz stacktrace.Zaloguj się do przeglądarki (wolę less stacktrace.log na Linuksie)... raz w przeglądarce, Szukaj .groovy i .gsp... to zazwyczaj prowadzi cię do tego, na czym Ci zależy.
  • gdy stacktrace odnosi się do numeru linii w pliku GSP, należy otworzyć ten widok w przeglądarce z ?showSource w łańcuchu zapytania, tzn. http://localhost:8080/myProject/myController/myAction?showSource... pokazuje skompilowane źródło GSP i wszystkie numery linii GSP w stacktrace odnosi się do skompilowanego GSP, a nie do rzeczywistego źródła GSP
  • zawsze, zawsze, zawsze otaczaj swoje zapisy przynajmniej minimalnym błędem obsługi.

Przykład:

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()
    }
}
Poza tym wiele z nich sprowadza się do rozpoznawania ścieżek stosu i komunikatów o błędach... Grails często nie jest pomocny w komunikatach o błędach, ale możesz nauczyć się rozpoznawać wzorce, takie jak:
  • niektóre z najtrudniejsze błędy do zrozumienia są dlatego, że nie uruchomiłeś grails clean lub grails upgrade... aby uniknąć tych problemów, zawsze używam następującego wiersza poleceń, aby uruchomić grails: grails clean; yes | grails upgrade; grails run-app
  • Jeśli błąd ma związek ze zduplikowanymi definicjami klasy, upewnij się, że zadeklarujesz pakiet, do którego należy klasa na górze pliku klasy
  • Jeśli błąd ma związek z metadanymi schematu, połączeniem, gniazdem lub tym podobne, upewnij się, że złącze bazy danych znajduje się w lib/, upewnij się, że Twoje uprawnienia są poprawne zarówno w DataSource.groovy, jak i w bazie danych dla nazwy użytkownika, hasła i hosta, i upewnij się, że znasz tajniki wersji złącza (np. mysql connector w wersji 5.1.X ma dziwny problem z aliasami, które mogą wymagać ustawienia useOldAliasMetadataBehavior=true na adresie url w DataSource.groovy)

I tak dalej. Istnieje wiele wzorców, które trzeba nauczyć się rozpoznawać.

 32
Author: Chris King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-04 20:31:20
  • Aby dodać do sugestii Chrisa Kinga na temat save, napisałem zamknięcie wielokrotnego użytku:

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

Wtedy możesz go używać wszędzie i zajmie się raportowaniem błędów:

  def book = new Book(authorName:"Mark Twain")
  saveClosure(book)
  • Dodatkowo, używam debug plugin - pozwala na dodatkowe logowanie, i dodałem tag na dole mojej głównej-który daje mi Widok wszystkich zmiennych w sesji / żądanie.

  • Runtime Logging plugin pozwala na włączenie logowania w runtime.

  • Podczas pisania tej odpowiedzi, p6spy plugin również wydaje się, że może to być przydatne - rejestruje wszystkie oświadczenia aplikacja sprawia, że przeciwko bazie danych, działając jako proxy.

  • Przydatna jest również konsola Grails. Używam go do interaktywnego szturchania i eksperymentowania z kodem, który również przydaje się podczas debugowania.

  • I oczywiście możliwość przejścia przez Debugger jest słodka. Przesiadłem się na IntelliJ IDEA ponieważ ma najlepszy Grails / Groovy support.

 16
Author: Jean Barmash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-16 21:19:00

Zapytałem kiedyś doświadczonego programistę groovy o to, jak skutecznie debuguje swoje aplikacje. Jego odpowiedź:

Piszę testy!

I ma bardzo dobry punkt: Jeśli Twój kod ma wystarczającą ilość testów jednostkowych i integracyjnych, prawie nigdy nie będziesz musiał niczego debugować. Poza tym możesz mówić takie zadowolone rzeczy swoim kolegom deweloperom...

Dla Grali:

 14
Author: mycro.be,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-20 19:41:35

Aby zalogować wyjątki za pomocą GrailsUtil.

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

Więcej informacji o sanitize.

 7
Author: user2427,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-12 18:27:40

Dodanie tego kodu do Bootsrapa.groovy: init nadpisze metodę save i wykona inny kod, wypisując w tym przypadku komunikaty o błędach.

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


            }
        }
...
}

Mam nadzieję, że komuś to pomoże:)

(I know its not really DRY)

Ref: http://grails.1312388.n4.nabble.com/How-to-override-save-method-on-domain-class-td3021424.html

 5
Author: nils petersohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 20:48:54

Nie jestem pewien, czy można to zrobić po wyjęciu z pudełka, ale w webapps uważam, że warto mieć " kim jestem?"funkcja w różnych plikach widoku.

Chodzi o to, aby emitować wiadomość do renderowanego HTML, aby zidentyfikować fragment. Jest to szczególnie ważne, gdy napotykam aplikację po raz pierwszy.

W Grails, robię to za pomocą niestandardowego znacznika. Na przykład rozważ listę.gsp dla ucznia:

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

Oto kod:

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

Kluczem jest to, że możesz zostawić te znaczniki tam, w razie potrzeby, ponieważ pojawiają się tylko wtedy, gdy tryb jest włączony w Config.groovy: {]}

grails.views.debug.mode=true
 4
Author: Michael Easter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-02 01:48:54

Patrząc na kod źródłowy! To uratowało mnie już tyle razy! A teraz, gdy kod jest hostowany na Githubie, jest to łatwiejsze niż kiedykolwiek. Po prostu naciśnij "t" i zacznij pisać, aby znaleźć klasę, której szukasz!

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

 4
Author: Kimble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-30 15:11:26

Oto kilka trików zebranych przez @ groovymag od ludzi Grails na Twitterze:

Http://blog.groovymag.com/2009/02/groovygrails-debugging/

 2
Author: chanwit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-12 00:36:14

Do prostych aplikacji używam println statement.It to bardzo prosta sztuczka.Dla złożonych aplikacji Użyj trybu debugowania w intellij idea.

 1
Author: DonX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-18 04:16:56