加载Groovy文件时捕获异常 [英] Catching an exception when loading a groovy file
问题描述
我有以下3个groovy文件:
I have these 3 groovy files:
A.groovy:
// ...
stage("Test")
{
throw new Exception("This script fails")
}
B.groovy:
// ...
stage("Test")
{
// Nothing, want this to pass
}
main.groovy:
main.groovy:
// ...
m = [:]
status = [:]
scripts = ["A", "B"]
for script in scripts
{
m["${script}"] =
{
stage("${script}")
{
try
{
load "${script}.groovy"
status["${script}"] = true
}
catch (Exception e)
{
status["${script}"] = false
}
}
}
}
parallel m
for result_iterator in status:
print "${result_iterator.key} resulted in ${result_iterator.value}"
上面的代码是真实代码的草图=) 当我运行main.groovy在状态字典中查看结果时,我只会看到B.A抛出异常,因此它没有将自身添加到字典中.有什么办法可以某种方式捕获A的异常吗?
The code above is a sketch of the real code =) When I run main.groovy to see the results in the status dictionary, I only get to see B. A threw an exception and thus it didn't add itself to the dictionary. Is there a way I can catch A's exception somehow?
推荐答案
问题1
您被Groovy闭包捕获超出其范围的变量的方式所困扰.闭包内部对script
的引用在运行闭包时将收到script
的值,该值将是script
的最后一个值.因此,两个闭包实际上都加载"B.groovy" ,并且永远不会引发异常!
Problem 1
You got bitten by the way Groovy closures capture variables outside of their scope. The references to script
inside the closure will receive the value of script
at the time when the closure is run, which will be the last value of script
. So both closures actually load "B.groovy" and the exception is never thrown!
修复很简单,只需在循环内部创建一个捕获script
当前值的局部变量即可:
The fix is simple, just create a local variable inside of the loop that captures the current value of script
:
for( script in scripts ) {
def theScript = script
// Now only use theScript inside of the closure!
}
问题2
您没有在序列化从parallel
线程对status
变量的写访问.这可能会导致非常令人讨厌,难以重现的错误.
Problem 2
You are not serializing write access to the status
variable from parallel
threads. This could result in very nasty, hard-to-reproduce bugs.
解决方法是使用同步地图:
status = [:].asSynchronized()
完成"main.groovy"修复
m = [:]
status = [:].asSynchronized() // because multiple threads write to this variable
scripts = ["A", "B"]
for( script in scripts ) {
def theScript = script // Important to pass the current value into the closure!
m[ theScript ] = {
stage( theScript ) {
try {
load "${theScript}.groovy"
status[ theScript ] = true
}
catch (Exception e) {
status[ theScript ] = false
}
}
}
}
parallel m
for( result_iterator in status ) {
print "${result_iterator.key} resulted in ${result_iterator.value}"
}
注意:我还删除了不必要的字符串插值.
Note: I have also removed the unnecessary string interpolations.
这篇关于加载Groovy文件时捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!