The following code will throw a grails.validation.ValidationException if the save fails for some reason. But the result is a generic error. How can I know the actual cause of the error so I can report it back to the user?
def addChild(cName,Parent theParent) {
println "add child: ${cName}"
def theChild = new Child(name:cName,parent:theParent)
theChild.save(failOnError:true)
return theChild
}
This is the stack trace returned. I happen to know that it's caused by violating a unique contsraint, because I caused it on purpose, but there's nothing in the trace to indicate that was cause vs. some other constraint violation.
org.codehaus.groovy.runtime.InvokerInvocationException: grails.validation.ValidationException: Validation Error(s) Occurred During Save
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
Caused by: grails.validation.ValidationException: Validation Error(s) Occurred During Save
at AddRecordsService.addChild(AddRecordsService.groovy:30)
at AddRecordsService$addChild.callCurrent(Unknown Source)
at AddRecordsService.addAll(AddRecordsService.groovy:11)
at AddRecordsService$$FastClassByCGLIB$$e47d68f4.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at AddRecordsService$$EnhancerByCGLIB$$cdfdcc61.addAll(<generated>)
at AddRecordsService$addAll.call(Unknown Source)
at AddrecordController$_closure2.doCall(AddrecordController.groovy:14)
at AddrecordController$_closure2.doCall(AddrecordController.groovy)
... 32 more
Update
OK, it seems that at least for now, the only way to get a transaction to roll back AND figure out what caused the error is to check if the save failed, get the failedobject.errors and throw a RuntimeException. But now how do you pass the errors back to the calling controller? The following doesn't work.
def addChild(cName,Parent theParent) {
println "add child: ${cName}"
def theChild = new Child(name:cName,parent:theParent)
//theChild.save(failOnError:true)
//theChild.save()
if(!theChild.save()){
println theChild.errors
throw new RuntimeException(theChild.errors)
//throw new RuntimeException('unable to save child')
}
return theChild
}