development

가장 좋아하는 Grails 디버깅 트릭은 무엇입니까?

big-blog 2020. 12. 30. 20:18
반응형

가장 좋아하는 Grails 디버깅 트릭은 무엇입니까?


Grails는 긴 스택 덤프로 디버깅하는 데 약간의 부담이 될 수 있습니다. 문제의 원인을 파악하는 것은 까다로울 수 있습니다. 예를 들어 "def foo = new Foo (a : a, b : b) .save ()"를 수행하면서 BootStrap.groovy에서 몇 번 구워졌습니다. Grails 앱을 디버깅 할 때 가장 좋아하는 트릭은 무엇입니까?


몇 가지 일반적인 팁 :

  • stacktrace.log를 지우고 grails run-app을 수행 한 다음 뷰어에서 stacktrace.log를 엽니 다 ( less stacktrace.logLinux에서 선호 함). 뷰어에서 .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 clean이거나 grails upgrade... 이러한 문제를 피하기 위해 명령 줄에서 항상 다음을 사용하여 grails를 실행합니다.grails clean; yes | grails upgrade; grails run-app
  • 오류가 클래스의 중복 정의와 관련이있는 경우 클래스 파일의 맨 위에 클래스가 속한 패키지를 선언해야합니다.
  • 오류가 스키마 메타 데이터, 연결, 소켓 또는 이와 관련된 것과 관련이있는 경우 데이터베이스 커넥터가에 lib/있는지 확인 DataSource.groovy하고 사용자 이름, 비밀번호 및 호스트에 대한 데이터베이스 내부 및 내부의 권한이 올바른지 확인하고 커넥터 버전의 내용을 알고 있음 (예 : mysql 커넥터 버전 5.1.X에는 useOldAliasMetadataBehavior=true의 URL에 설정해야하는 별칭에 이상한 문제가 있음 DataSource.groovy)

등등. 인식하는 법을 배울 수있는 많은 패턴이 있습니다.


  • 저장에 대한 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)
  • 또한 디버그 플러그인을 사용합니다. 추가 로깅을 허용하고 메인 하단에 태그를 추가하여 세션 / 요청의 모든 변수를 볼 수 있습니다.

  • 런타임 로깅 플러그인을 사용하면 런타임에 로깅 을 활성화 할 수 있습니다.

  • 이 답변을 작성하는 동안 P6SPY 플러그인 도 유용 할 것으로 보입니다. 앱이 프록시 역할을하여 데이터베이스에 대해 작성하는 모든 명령문을 기록합니다.

  • Grails Console도 유용합니다. 나는 그것을 대화식으로 둘러보고 몇 가지 코드를 실험하는 데 사용합니다. 이는 디버깅 중에도 유용합니다.

  • 물론 디버거를 단계별로 진행할 수 있다는 점은 매우 좋습니다. Grails / Groovy 지원이 가장 좋은 IntelliJ IDEA로 전환했습니다.


나는 경험 많은 그루비 개발자에게 그가 자신의 애플리케이션을 효과적으로 디버깅하는 방법에 대해 물었다. 그의 대답 :

나는 테스트를 작성합니다!

그리고 그는 매우 좋은 점을 가지고 있습니다. 코드에 충분한 단위 및 통합 테스트가 있으면 디버그 할 필요가 거의 없습니다. 또한 동료 개발자들에게 그런 잘난 척하는 말을 할 수 있습니다.

Grails의 경우 :


GrailsUtil로 예외를 기록하려면.

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

살균에 대한 자세한 정보.


이 코드를 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


I'm not sure if this can be done out-of-the-box, but in webapps I find it useful to have a "who am I?" facility in the various view files.

The idea is to emit a message into the rendered HTML, to identify the fragment. This is especially true when I am encountering an app for the first time.

In Grails, I do this with a custom tag. For example, consider list.gsp for a Student:

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

Here is the code:

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

The key is that you can leave those tags in there, if desired, as they only appear in when the mode is enabled in Config.groovy:

grails.views.debug.mode=true

Looking at the source code! This has saved me so many times now! And now that the code is hosted at GitHub it's easier than ever. Just press "t" and start typing to find the class that you're looking for!

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


Here's some tricks collected by @groovymag from Grails people in twitter:

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


For simple applications I use println statement.It is very very easy trick.For complex applications use debug mode in intellij idea.

ReferenceURL : https://stackoverflow.com/questions/536601/what-are-your-favorite-grails-debugging-tricks

반응형