为什么在使用断言语句抛出异常后,Groovy脚本会无限挂起?

huangapple go评论42阅读模式
英文:

Why does a Groovy script hang indefinitely after throwing an exception using the assert statement?

问题

我有一个 verify.groovy 脚本,使用 evaluate() 函数执行多个 Groovy 脚本。其中一个脚本,first-check.groovy,使用 assert 语句故意引发异常。然而,verify.groovy 脚本似乎无限期地挂起,而不是以错误消息优雅地退出。

这是 verify.groovy 的代码:

[
  'first-check.groovy',
  'second-check.groovy'
].each {
  evaluate(basedir.toPath().resolve(it).toFile())
  println String.format('验证 %s - OK', it)
}

以及 first-check.groovy 的代码:

assert 1 == 2
true

异常:

在线程 "main" 中的异常:
Assertion failed: 

assert 1 == 2
         |
         false

        at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:432)

<--- 在此挂起,直到我通过 Ctrl+C 或 command+C 中断进程

为什么脚本不是以错误消息完成,而是无限期地挂起?我该如何修复它?

英文:

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:

[
  &#39;first-check.groovy&#39;,
  &#39;second-check.groovy&#39;
].each {
  evaluate(basedir.toPath().resolve(it).toFile())
  println String.format(&#39;Verified with %s - OK&#39;, it)
}

And the code for first-check.groovy:

assert 1 == 2
true

Exception:

Exception in thread &quot;main&quot; Assertion failed: 

assert 1 == 2
         |
         false

        at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:432)

&lt;--- 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?

答案1

得分: 2

each和类似方法中的异常处理很棘手,所以你必须手动捕获并重新抛出异常:

String first = &#39;&#39;&#39;\
assert 1 == 2 
true&#39;&#39;&#39;
String second = &#39;&#39;&#39;\
assert true
true&#39;&#39;&#39;

[ first, second ].eachWithIndex{ it, ix -&gt;
  try{
    def res = evaluate it
    println &quot;Verified $ix with $res&quot;
  }catch( Throwable t ){
    println &quot;Check $ix failed miserably: $t&quot;
    throw t // &lt;&lt; 重新抛出!
  }
}

println &#39;end reached&#39;

在这种情况下,你将在控制台中看到以下输出:

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)

如果你注释掉重新抛出的那行,输出将会是:

Check 0 failed miserably: Assertion failed: 

assert 1 == 2
         |
         false

Verified 1 with true
end reached

话虽如此,更好的迭代脚本的选项是使用普通的for循环:

int ix = 0
for( it in [ first, second ] ){
  def res = evaluate it
  println &quot;Verified $ix with $res&quot;
  ix++
}

在这种情况下,异常将被传播而不会阻塞。

英文:

The exception handling in each and alike methods is tricky, so you have to catch and re-throw the exception manually:

String first = &#39;&#39;&#39;\
assert 1 == 2 
true&#39;&#39;&#39;
String second = &#39;&#39;&#39;\
assert true
true&#39;&#39;&#39;

[ first, second ].eachWithIndex{ it, ix -&gt;
  try{
    def res = evaluate it
    println &quot;Verified $ix with $res&quot;
  }catch( Throwable t ){
    println &quot;Check $ix failed miserably: $t&quot;
    throw t // &lt;&lt; re-throw!
  }
}

println &#39;end reached&#39;

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 &quot;Verified $ix with $res&quot;
  ix++
}

In this case the exception with be propagated without blocking.

huangapple
  • 本文由 发表于 2023年3月3日 18:56:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75626178.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定