web-dev-qa-db-ja.com

お気に入りのGrailsデバッグトリックは何ですか?

Grailsは、その長いスタックダンプでデバッグするのが少し難しいかもしれません。問題の原因を突き止めるのは難しい場合があります。たとえば、BootStrap.groovyで「def foo = new Foo(a:a、b:b).save()」を実行して、何度か書き込みました。 Grailsアプリをデバッグするためのお気に入りのトリックは何ですか?

56
anon

一般的なヒント:

  • 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 cleanまたはgrails upgrade...を実行しなかったため、最も理解しにくいエラーのいくつかは、Grailsを実行するためにコマンドラインで常に次のコマンドを使用します:grails clean; yes | grails upgrade; grails run-app
  • エラーがクラスの重複定義に関係している場合は、クラスが属するパッケージをクラスのファイルの先頭で宣言していることを確認してください
  • エラーがスキーマメタデータ、接続、ソケットなどに関係している場合は、データベースコネクタがlib/にあることを確認し、DataSource.groovyとデータベースの両方で権限が正しいことを確認してくださいユーザー名、パスワード、ホスト、およびコネクタのバージョンの詳細を確認してください(つまり、mysqlコネクタバージョン5.1.Xには、エイリアスの奇妙な問題があり、URLにuseOldAliasMetadataBehavior=trueを設定する必要がある場合があります。 DataSource.groovy

等々。認識することを学ぶためのパターンはたくさんあります。

33
Chris King
  • 保存に関する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 を使用します。これにより、追加のロギングが可能になり、メインの下部にタグを追加しました。これにより、セッション/リクエスト内のすべての変数のビューが表示されます。

  • 実行時ログプラグイン 実行時にログを有効にすることができます。

  • この回答を書いている間、 P6SPYプラグイン も役立つと思われます-プロキシとして機能することにより、アプリがデータベースに対して行ったすべてのステートメントをログに記録します。

  • Grails Consoleも役立ちます。私はそれを使ってインタラクティブに調べたり、いくつかのコードを試したりします。これはデバッグ中にも役立ちます。

  • そしてもちろん、デバッガーをステップスルーできることはすばらしいことです。 IntelliJに切り替えましたIDEAそれは最高のGrails/Groovyサポートを持っているからです。

16
Jean Barmash

経験豊富なグルーヴィーな開発者に、アプリケーションを効果的にデバッグする方法を聞いたことがあります。彼の答え:

テストを書く!

そして、彼は非常に良い点を持っています:コードに十分な単体テストと統合テストがあれば、何もデバッグする必要はほとんどありません。さらに、あなたはあなたの仲間の開発者にそのような独善的なことを言うようになります...

Grailsの場合:

14
mycro.be

GrailsUtilで例外をログに記録します。

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

サニタイズの詳細

7
user2427

このコードを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: http://grails.1312388.n4.nabble.com/How-to-override-save-method-on-domain-class-td3021424.html

5
nils petersohn

これをすぐに実行できるかどうかはわかりませんが、Webアプリでは「私は誰ですか?」さまざまなビューファイルの機能。

アイデアは、フラグメントを識別するために、レンダリングされた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
4
Michael Easter

ソースコードを見て!これは今私を何度も救ってくれました!コードがGitHubでホストされるようになったため、これまでになく簡単になりました。 「t」を押して入力を開始するだけで、探しているクラスを見つけることができます。

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

4
Kimble

以下は、TwitterのGrailsの人々から@ groovymag が収集したトリックです。

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

2
chanwit

単純なアプリケーションでは、printlnステートメントを使用します。これは非常に簡単なトリックです。複雑なアプリケーションでは、intellijのアイデアでデバッグモードを使用します。

1
DonX