How do I print a Groovy stack trace?
How do I print a Groovy stack trace? The Java method, Thread.currentThread().getStackTrace() produces a huge stack trace, including a lot of the Groovy internals. I'm seeing a function call开发者_运维技巧ed twice from a StreamingMarkupBuilder that looks like it should only be called once and I would like to see why Groovy thinks it should be calling it twice.
Solution:
org.codehaus.groovy.runtime.StackTraceUtils.sanitize(new Exception()).printStackTrace()
Original answer:
A Google search returns the following information:
Apparently, there is a method in org.codehaus.groovy.runtime.StackTraceUtils
called printSanitizedStackTrace
. There isn't much documentation for the method, though there is a method called sanitize
which is described as
remove all apparently groovy-internal trace entries from the exception instance This modifies the original instance and returns it, it does not clone
So I would try org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(Throwable t)
(it is static)
and see if that works for you.
I found this questions when searching for "spock print full stack trace"
.
My unit tests are written in Groovy, using the Spock testing framework and they're run in the context of a Gradle build.
The fix for me was as simple as adding exceptionFormat = 'full'
to my Gradle test task specification:
test {
testLogging {
exceptionFormat = 'full'
}
}
I have designed this simple code for stack trace printing, based on artificial simulation of a NullPointerException. This code produces the same output in both modes: from a Jenkinsfile (Pipeline) and from a normal .groovy script in a command line.
def getStackTrace() {
try {
null.class.toString() // simulate NPE
} catch (NullPointerException e) {
return e.getStackTrace()
}
return null
}
def printStackTrace() {
def stackTraceStr = ""
def callingFuncFound = false
for (StackTraceElement ste : getStackTrace()) {
if (callingFuncFound) {
stackTraceStr += ste.toString() + '\n'
}
if (!callingFuncFound && ste.toString().startsWith(this.class.name + '.printStackTrace(')) {
callingFuncFound = true
}
}
println(stackTraceStr)
}
Some explanations:
- The output is concatenated into a single string to avoid being mixed with "[Pipeline] echo" message prefix of Jenkins Pipeline's println()).
- The number of "unnecessary" upper stack trace elements related to the NPE is different in Jenkinsfile and in a normal command line. This is why I calculate callingFuncFound and don't use just something like e.getStackTrace()[2..-1] to skip them.
精彩评论