首页 文章

你最喜欢的Grails调试技巧是什么? [关闭]

提问于
浏览
54

通过长堆栈转储,Grails可能有点像熊一样调试 . 找到问题的根源可能很棘手 . 我在BootStrap.groovy中做过几次烧伤,例如“def foo = new Foo(a:a,b:b).save()” . 您最喜欢调试Grails应用程序的技巧是什么?

9 回答

  • 4

    一些一般提示:

    • 清除stacktrace.log,运行grails run-app,然后在查看器中打开stacktrace.log(我更喜欢linux上的 less stacktrace.log )...一次在你的查看器中,搜索.groovy和.gsp ...这通常会带你到你真正关心的是什么 .

    • 当堆栈跟踪引用GSP文件中的行号时,您应该在浏览器中使用 ?showSource 在查询字符串中打开该视图,即 http://localhost:8080/myProject/myController/myAction?showSource ...这显示已编译的GSP源,并且堆栈跟踪中的所有GSP行号引用到编译的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()
        }
    }
    

    除此之外,很多东西只是归结为识别堆栈跟踪和错误消息......很多时候,Grails在它给你的错误消息中非常无益,但你可以学会识别模式,如下所示:

    • 一些最难理解的错误是因为你没有运行 grails cleangrails upgrade ...以避免这些问题,我总是在命令行上使用以下命令来运行grails: grails clean; yes | grails upgrade; grails run-app

    • 如果错误与类的重复定义有关,请确保在类的文件顶部声明类所属的包

    • 如果错误与架构元数据,连接,套接字或类似内容有关,请确保数据库连接器位于 lib/ 中,请确保 DataSource.groovy 和数据库中的用户名,密码和主机的权限都正确,并确保你知道你的连接器版本的来龙去脉(即mysql连接器版本5.1.X有一个奇怪的问题,可能需要你在 DataSource.groovy 的网址上设置 useOldAliasMetadataBehavior=true 的别名)

    等等 . 有许多模式需要学会识别 .

  • 7
    • 为了补充Chris King关于保存的建议,我写了一个可重复使用的闭包:
    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)
    
    • 此外,我使用了debug plugin - 它允许额外的日志记录,我在主要的底部添加了标记 - 这使我能够查看会话/请求中的所有变量 .

    • Runtime Logging plugin允许在运行时启用日志记录 .

    • 在写这个答案时,P6SPY plugin似乎也很有用 - 它通过充当代理来记录您的应用程序对数据库所做的所有语句 .

    • Grails控制台也很有用 . 我用它来交互式地浏览并试验一些代码,这些代码在调试时也很方便 .

    • 当然,能够通过调试器是很好的 . 我切换到IntelliJ IDEA,因为它具有最好的Grails / Groovy支持 .

  • 5

    我曾经问过一位经验丰富的常规开发人员,他是如何有效地调试他的应用程序的 . 他的回答是:

    我写测试!

    他有一个非常好的观点:如果你的代码有足够的单元和集成测试,你几乎不需要调试任何东西 . 另外,你可以向你的开发人员说出类似的东西......

    对于Grails:

  • 32

    使用GrailsUtil记录异常 .

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

    More info about sanitize.

  • 1

    将此代码添加到Bootsrap.groovy:init将覆盖save方法并执行其他一些代码,在这种情况下打印出错误消息 .

    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

  • 14

    我不确定这是否可以开箱即用,但在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>
    " } } }

    关键是,如果需要,您可以将这些标签保留在那里,因为它们仅在Config.groovy中启用模式时出现:

    grails.views.debug.mode=true
    
  • 16

    看源代码!这已经让我多次拯救了我!现在那个了代码在GitHub上托管,比以往更容易 . 只需按“t”键即可开始输入以查找您正在寻找的课程!

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

  • 2

    以下是来自Grails的Twitter @ groovymag收集的一些技巧:

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

  • 4

    对于简单的应用程序,我使用println语句 . 这是非常容易的技巧 . 对于复杂的应用程序,在intellij的想法中使用调试模式 .

相关问题