Jenkins CPS Groovy没有捕获NoSuchMethodError异常

时间:2020-09-16 20:08:02

标签: groovy jenkins-pipeline jenkins-groovy

当groovy代码调用不存在的方法时,是否仍会捕获NoSuchMethodError错误?

以下代码导致NoSuchMethodError错误,该错误未捕获,但finally块确实执行。这给我的一些错误处理和报告带来了麻烦。

带有伪造的dsl的代码

try {
    println "in try"
    dslDoesNotExist()
} catch (Exception ex) {
    println "Caught error ${ex}"
    throw ex
} finally {
    println "finally block"
}

结果

in try
[Pipeline] echo
finally block    // see the finally but not the catch
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
java.lang.NoSuchMethodError: No such DSL method 'dslDoesNotExist'

如果我修改要引用不存在的属性/变量的代码,则会处理catch块

缺少属性的代码

try {
    println "in try"
    propertyOrVariableDoesNotExist
} catch (Exception ex) {
    println "Caught error ${ex}"
    throw ex
} finally {
    println "finally block"
}

结果

in try
[Pipeline] echo
Caught error groovy.lang.MissingPropertyException: No such property: propertyOrVariableDoesNotExist for class: WorkflowScript
[Pipeline] echo
finally block
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: propertyOrVariableDoesNotExist for class: 

这是怎么回事

Java与Groovy异常?

CPS groovy catch(Ex exException)是否可以捕获java.lang。例外?不

代码

    try {
        throw new java.lang.NoSuchMethodError("dsl problem")
    } catch (Exception ex) {
        println "Caught"
    }

结果

    // No evidence of the catch
    
    [Pipeline] { (hide)
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] End of Pipeline
    java.lang.NoSuchMethodError: dsl problem

1 个答案:

答案 0 :(得分:2)

感谢@ jeff-scott-brown的正确。经过一些挖掘和实验才能弄清楚这一点。我弄错了。

NoSuchMethodError的祖先看起来像

 java.lang.Object
    java.lang.Throwable
        java.lang.Error
            java.lang.LinkageError
                java.lang.IncompatibleClassChangeError
                    java.lang.NoSuchMethodError 

Groovy Exception的祖先是

java.lang.Throwable
    java.lang.Exception
        org.codehaus.groovy.GroovyException 

因此,如果我将代码重构为此,它将按预期工作。最初测试时,我遇到了一个安全沙箱错误,该错误使结果模糊不清,但我错过了它(它很刺眼,所以我不知道我怎么错过它,但是我做到了)

代码

try {
    dslNotExist()
} catch (java.lang.Throwable ex) {
    println "Caught"
}

结果

[Pipeline] {
[Pipeline] echo
Caught
[Pipeline] }
[Pipeline] // node