Debugging 您最喜欢的Grails调试技巧是什么?
Grails可以通过其长堆栈转储进行调试。找到问题的根源可能很棘手。例如,我在BootStrap.groovy中做了几次“def foo=new foo(a:a,b:b).save()”时被烧坏了。调试Grails应用程序时,您最喜欢的技巧是什么?以下是@from Grails people在twitter上收集的一些技巧: 一些一般提示:Debugging 您最喜欢的Grails调试技巧是什么?,debugging,grails,Debugging,Grails,Grails可以通过其长堆栈转储进行调试。找到问题的根源可能很棘手。例如,我在BootStrap.groovy中做了几次“def foo=new foo(a:a,b:b).save()”时被烧坏了。调试Grails应用程序时,您最喜欢的技巧是什么?以下是@from Grails people在twitter上收集的一些技巧: 一些一般提示: 清除stacktrace.log,运行grails应用程序,然后在查看器中打开stacktrace.log(我更喜欢在linux上少一点stacktrac
- 清除stacktrace.log,运行grails应用程序,然后在查看器中打开stacktrace.log(我更喜欢
)。。。进入查看器后,搜索.groovy和.gsp。。。这通常会让你了解你真正关心的事情。在linux上少一点stacktrace.log
- 当stacktrace引用GSP文件中的行号时,应在浏览器中使用查询字符串中的
打开该视图,即?showSource
。。。这显示了已编译的GSP源,stacktrace中的所有GSP行号都是指已编译的GSP,而不是实际的GSP源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()
}
}
除此之外,很多都归结为识别堆栈跟踪和错误消息。。。很多时候,Grails在它给您的错误消息中毫无帮助,但您可以学习识别模式,如以下所示:- 一些最难理解的错误是因为您没有运行
或grailsclean
。。。为了避免这些问题,我总是在命令行上使用以下命令来运行grails:grailsgrade
GrailsClean;是| grails升级;grails run应用程序
- 如果错误与类的重复定义有关,请确保在类文件的顶部声明该类所属的包
- 如果错误与架构元数据、连接、套接字或类似内容有关,请确保您的数据库连接器位于
中,确保您在lib/
DataSource.groovy以及数据库中对用户名、密码和主机的权限正确,并确保您了解连接器版本的详细信息(即mysql连接器版本5.1.X的别名有一个奇怪的问题,可能需要您在
中的url上设置数据源.groovy
)useOldAliasMetadataBehavior=true
- 为了补充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)
- 此外,我使用-它允许额外的日志记录,并且我在main的底部添加了标记-它为我提供了会话/请求中所有变量的视图
- 允许在运行时启用日志记录
- 在写这个答案时,它似乎也很有用——它通过代理的方式记录你的应用程序对数据库所做的所有声明
- Grails控制台也很有用。我使用它以交互方式浏览和实验一些代码,这在调试过程中也很方便
- 当然,能够一步一步地通过调试器是件好事。我转而使用IntelliJ IDEA,因为它具有最好的Grails/Groovy支持
- 非常优秀的grails应用程序测试
<g:debug msg="student list" />
使用GrailsUtil记录异常
try{
...
}catch (Exception e){
log.error("some message", GrailsUtil.sanitize(e))
...
}
查看源代码!这救了我很多次!现在代码托管在GitHub上,比以往任何时候都简单。只需按“t”并开始键入即可找到您要查找的类
将此代码添加到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
}
}
...
}
希望对某人有所帮助:)
(我知道它不是很干)
ref:我很高兴看到我们终于有了一颗银弹。WTF?那么,当他的测试失败时,他是如何调试代码的呢?还是他的代码从来没有通过测试?在这种情况下,他只是测试他知道会起作用的东西?这是一个非常奇怪的说法,我觉得这是重复的。更不用说你说的自鸣得意了。西蒙&WTF对写作测试的反应。。。您可以尝试将日志添加到测试中。@如果您可以一次测试一个组件而不是整个应用程序,则Simon调试会容易得多。最近记忆中的最佳问题…@MichaelEaster seconded。因此认为这些知识库文章没有建设性,这真是一个遗憾。答案投票系统提供了一个优秀的系统,可以将提示从最有用到最不有用进行集体排序,这比维基风格的知识库要有用得多。saveClosure(x)真的那么groovy吗?当然重写save()方法会更好吗?不要再麻烦p6spy了。使用SpringInsight。它具有p6spy的所有功能,无需c
try{
...
}catch (Exception e){
log.error("some message", GrailsUtil.sanitize(e))
...
}
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
}
}
...
}