开发者

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:

  1. The output is concatenated into a single string to avoid being mixed with "[Pipeline] echo" message prefix of Jenkins Pipeline's println()).
  2. 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.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜