debugging - intellij - ¿Cuáles son tus trucos de depuración favoritos de Grails?
depurar en intellij (9)
Algunos consejos generales:
- Borre stacktrace.log, ejecute run-run-app, luego abra stacktrace.log en un visor (prefiero
less stacktrace.log
en Linux) ... una vez en su visor, busque .groovy y .gsp ... eso generalmente trae a lo que realmente te importa - Cuando un stacktrace se refiere a un número de línea en un archivo GSP, debe abrir esa vista en un navegador con
?showSource
en la cadena de consulta, es decir,http://localhost:8080/myProject/myController/myAction?showSource
... esto muestra la fuente GSP compilada, y todos los números de línea GSP en la pila stack se refieren al GSP compilado, no a la fuente real GSP - Siempre, siempre, siempre rodee sus salvaciones con al menos un manejo de error mínimo.
Ejemplo:
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()
}
}
Más allá de eso, una gran parte de esto se reduce a reconocer trazas de pila y mensajes de error ... muchas veces, Grails es increíblemente inútil en los mensajes de error que te da, pero puedes aprender a reconocer patrones, como los siguientes:
- Algunos de los errores más difíciles de entender son porque no ejecutó
grails clean
ograils upgrade
... para evitar estos problemas, siempre utilizo lo siguiente en la línea de comandos para ejecutar grails:grails clean; yes | grails upgrade; grails run-app
grails clean; yes | grails upgrade; grails run-app
- Si el error tiene que ver con las definiciones duplicadas de una clase, asegúrese de declarar el paquete al que pertenece la clase en la parte superior del archivo de la clase
- Si el error tiene que ver con metadatos de esquema, conexión, socket o algo así, asegúrese de que el conector de su base de datos esté en
lib/
, asegúrese de que sus permisos sean correctos tanto enDataSource.groovy
como en la base de datos para nombre de usuario, contraseña y host, y asegúrese de conocer los pormenores de la versión de su conector (es decir, el conector mysql versión 5.1.X tiene un problema extraño con los alias que pueden requerir el uso deuseOldAliasMetadataBehavior=true
en la url enDataSource.groovy
)
Y así. Hay muchos patrones para aprender a reconocer.
Grails puede ser un poco difícil de solucionar con sus volcados de pila larga. Llegar a la fuente del problema puede ser complicado. Me han quemado varias veces en el BootStrap.groovy haciendo "def foo = new Foo (a: a, b: b) .save ()", por ejemplo. ¿Cuáles son tus trucos favoritos para depurar aplicaciones de Grails?
Aquí hay algunos trucos recopilados por @ groovymag de la gente de Grails en twitter:
Mirando el código fuente! ¡Esto me ha salvado tantas veces ahora! Y ahora que el código está alojado en GitHub es más fácil que nunca. ¡Simplemente presiona "t" y comienza a escribir para encontrar la clase que estás buscando!
No estoy seguro si esto se puede hacer desde el primer momento, pero en webapps encuentro útil tener un "¿quién soy?" instalación en los diversos archivos de vista.
La idea es emitir un mensaje en el HTML renderizado, para identificar el fragmento. Esto es especialmente cierto cuando me encuentro con una aplicación por primera vez.
En Grails, hago esto con una etiqueta personalizada. Por ejemplo, considere list.gsp para un Estudiante:
<g:debug msg="student list" />
Aquí está el código:
class MiscTagLib {
def debug = { map ->
if (grailsApplication.config.grails.views.debug.mode == true) {
def msg = map[''msg'']
out << "<h2>${msg}</h2><br/>"
}
}
}
La clave es que puede dejar esas etiquetas allí, si lo desea, ya que solo aparecen cuando el modo está habilitado en Config.groovy:
grails.views.debug.mode=true
Para aplicaciones simples, utilizo la declaración println. Es un truco muy fácil. Para aplicaciones complejas, use el modo de depuración en la idea inteligente.
Para registrar excepciones con GrailsUtil.
try{
...
}catch (Exception e){
log.error("some message", GrailsUtil.sanitize(e))
...
}
Una vez le pregunté a un desarrollador groovy con experiencia sobre cómo depuró efectivamente sus aplicaciones. Su respuesta:
¡Escribo pruebas!
Y tiene un muy buen punto: si su código tiene suficientes pruebas de unidad e integración, casi nunca necesitará depurar nada. Además, puedes decir cosas tan presumidas como esas a tus compañeros desarrolladores ...
Para Grails:
- Examen de la unidad
- Prueba Funcional
- Aplicación de Grails realmente excelente para probar el artículo de developerWorks
agregando este código a Bootsrap.groovy: init sobrescribirá el método de guardar y ejecutará también otro código, imprimiendo mensajes de error en este caso.
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
}
}
...
}
espero que ayude a alguien :)
(Sé que no es muy seco)
ref: http://grails.1312388.n4.nabble.com/How-to-override-save-method-on-domain-class-td3021424.html
Para agregar a la sugerencia de Chris King sobre guardar, escribí un cierre reutilizable:
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 } } }
Luego puede usarlo en todas partes y se ocupará de informar los errores:
def book = new Book(authorName:"Mark Twain")
saveClosure(book)
Además, utilizo el plugin de depuración - permite el registro adicional, y agregué la etiqueta al final de mi página principal - eso me da una vista de todas las variables en la sesión / solicitud.
El complemento Runtime Logging permite habilitar el registro en tiempo de ejecución.
Al escribir esta respuesta, el complemento P6SPY también parece que podría ser útil: registra todas las declaraciones que hace su aplicación contra la base de datos actuando como un proxy.
La consola de Grails también es útil. Lo uso para explorar y experimentar de forma interactiva con algún código, que también es útil durante la depuración.
Y, por supuesto, poder pasar por Debugger es dulce. Cambié a IntelliJ IDEA ya que tiene el mejor soporte de Grails / Groovy.