Подтвердить что ты не робот

Каковы ваши любимые отладочные трюки Grails?

Grails может быть немного медведя для отладки с его длинными отвалами. Получение источника проблемы может быть сложным. Я несколько раз сжег в BootStrap.groovy, например, "def foo = new Foo (a: a, b: b).save()". Каковы ваши любимые трюки для отладки приложений Grails?

4b9b3361

Ответ 1

Некоторые общие советы:

  • Очистить stacktrace.log, сделать grails run-app, а затем открыть файл stacktrace.log в средстве просмотра (я предпочитаю less stacktrace.log в linux)... один раз в вашем телезрителе, искать .groovy и .gsp..., что обычно приводит вас к тому, что вам действительно нужно.
  • Когда stacktrace ссылается на номер строки в файле GSP, вы должны открыть это представление в браузере с ?showSource в строке запроса, то есть http://localhost:8080/myProject/myController/myAction?showSource... это показывает скомпилированный источник GSP и все GSP номера строк в stacktrace относятся к скомпилированному GSP, а не к фактическому источнику GSP
  • Всегда, всегда, всегда окружайте ваши сбережения хотя бы с минимальной обработкой ошибок.

Пример:

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..., чтобы избежать этих проблем, я всегда использую следующее в командной строке для запуска grails: grails clean; yes | grails upgrade; grails run-app
  • Если ошибка связана с повторяющимися определениями класса, убедитесь, что вы объявили пакет, к которому принадлежит класс, в верхней части файла класса
  • Если ошибка связана с метаданными схемы, соединением, сокетом или чем-то подобным, убедитесь, что ваш соединитель базы данных находится в lib/, убедитесь, что ваши разрешения верны как в DataSource.groovy, так и в базе данных для имени пользователя, пароль и хост, а также убедитесь, что вы знаете, что в вашей версии разъема вы знаете (например, для версии mysql версии 5.1.X есть странная проблема с псевдонимами, которые могут потребовать установки useOldAliasMetadataBehavior=true на url в DataSource.groovy)

И так далее. Существует много шаблонов, которые нужно научиться распознавать.

Ответ 2

  • Чтобы добавить к предложению Криса Кинга о спасении, я написал многократное закрытие:

     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)
  • Кроме того, я использую отладочный плагин - он позволяет выполнять дополнительную регистрацию, и я добавил тег к нижней части моего основного - что дает мне представление обо всех переменных в сеансе/запросе.

  • Плагин ведения журнала выполнения позволяет включить ведение журнала во время выполнения.

  • При написании этого ответа плагин P6SPY также кажется, что он может быть полезен - он регистрирует все утверждения, сделанные вашим приложением против базы данных действуя в качестве доверенного лица.

  • Консоль Grails также полезна. Я использую его для интерактивного поиска и экспериментирования с некоторым кодом, который также пригодится во время отладки.

  • И, конечно, быть в состоянии пройти через Debugger сладко. Я переключился на IntelliJ IDEA, так как у него есть лучшая поддержка Grails/ Groovy.

Ответ 3

Однажды я спросил опытного разработчика groovy о том, как он эффективно отлаживал свои приложения. Его ответ:

Я пишу тесты!

И у него есть очень хорошая точка: если ваш код имеет достаточные тесты на единицу и интеграцию, вам вряд ли когда-либо придется отлаживать что-либо. Кроме того, вы можете сказать, что подобные вещи вам нравятся своим коллегам-разработчикам...

Для Grails:

Ответ 4

Заблокировать исключения с помощью GrailsUtil.

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

Подробнее о sanitize.

Ответ 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


            }
        }
...
}

надеюсь, что кто-то поможет:)

(я знаю его не очень СУХОЙ)

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

Ответ 6

Я не уверен, что это можно сделать из коробки, но в webapps я считаю полезным иметь "кто я?" объект в различных файлах просмотра.

Идея состоит в том, чтобы выпустить сообщение в визуализированный HTML, чтобы идентифицировать фрагмент. Это особенно актуально, когда я впервые сталкиваюсь с приложением.

В Grails я делаю это с помощью настраиваемого тега. Например, рассмотрим list.gsp для студента:

<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

Глядя на исходный код! Это спасло меня так много раз! И теперь, когда код размещен в GitHub, это проще, чем когда-либо. Просто нажмите "t" и начните вводить текст, чтобы найти класс, который вы ищете!

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

Ответ 9

Для простых приложений я использую инструкцию println. Это очень простой трюк. Для сложных приложений используется режим отладки в идее intellij.