I have a verify.groovy
script that executes multiple Groovy scripts using the evaluate()
function. One of the scripts, first-check.groovy
, intentionally throws an exception using the assert
statement. However, instead of exiting gracefully with the error message, the verify.groovy
script seems to hang indefinitely and never completes.
Here's the code for verify.groovy
:
[
'first-check.groovy',
'second-check.groovy'
].each {
evaluate(basedir.toPath().resolve(it).toFile())
println String.format('Verified with %s - OK', it)
}
And the code for first-check.groovy
:
assert 1 == 2
true
Exception:
Exception in thread "main" Assertion failed:
assert 1 == 2
|
false
at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:432)
<--- Hang here until I interrupt the process by Ctrl+C or command+C
Why does the script hang indefinitely instead of completing with the error message, and how can I fix it?
The exception handling in each
and alike methods is tricky, so you have to catch and re-throw the exception manually:
String first = '''\
assert 1 == 2
true'''
String second = '''\
assert true
true'''
[ first, second ].eachWithIndex{ it, ix ->
try{
def res = evaluate it
println "Verified $ix with $res"
}catch( Throwable t ){
println "Check $ix failed miserably: $t"
throw t // << re-throw!
}
}
println 'end reached'
In this case you will see this in the console:
Check 0 failed miserably: Assertion failed:
assert 1 == 2
|
false
Assertion failed:
assert 1 == 2
|
false
at Script1.run(Script1.groovy:1)
at Script1$_run_closure1.doCall(Script1.groovy:10)
at Script1.run(Script1.groovy:8)
If you comment the re-throw line out, the output will be:
Check 0 failed miserably: Assertion failed:
assert 1 == 2
|
false
Verified 1 with true
end reached
With that said, the better option to iterate through the scripts would be to use a plain for
loop:
int ix = 0
for( it in [ first, second ] ){
def res = evaluate it
println "Verified $ix with $res"
ix++
}
In this case the exception with be propagated without blocking.