【问题标题】:Retry after Exception in Groovy在 Groovy 中出现异常后重试
【发布时间】:2011-10-28 13:37:31
【问题描述】:

在 Ruby 中,我可以写:

begin
  do_something # exception raised
rescue
   # handles error
   retry  # restart from beginning
end

Groovy/Java 中有类似的东西吗?

我找到了this,但也许有更好的?

【问题讨论】:

    标签: java ruby exception groovy


    【解决方案1】:

    您可以在 Groovy 中构建自己的辅助方法来封装此重试逻辑。

    def retry(int times = 5, Closure errorHandler = {e-> log.warn(e.message,e)}
         , Closure body) {
      int retries = 0
      def exceptions = []
      while(retries++ < times) {
        try {
          return body.call()
        } catch(e) {
          exceptions << e
          errorHandler.call(e)
        }        
      }
      throw new MultipleFailureException("Failed after $times retries", exceptions)
    }
    

    (假设MultipleFailureException的定义类似于GPars' AsyncException

    那么在代码中,你可以如下使用这个方法。

    retry {
       errorProneOperation()
    }
    

    或者,使用不同的重试次数和错误处理行为:

    retry(2, {e-> e.printStackTrace()}) {
      errorProneOperation()
    }
    

    【讨论】:

    • 现在如果IllegalStateException 会使用其中一个异常(第一个?最后一个?很难说)作为其原因,它会更有用,因为你可以看到为什么它失败了。在生产中,我不希望每次尝试失败时都打印堆栈跟踪。如果所有重试都失败了,我只想知道它。
    • 感谢 Joachim - 根据您的建议,我在收集个别异常时已添加。至于不想要堆栈跟踪 - 当然,它只是为了说明这一点。由于现在正在收集异常以在最后报告,因此 errorHandler 的目的可能是在重试 body.call() 之前重置所需的任何资源 - 在这种情况下,默认关闭可能只是 {-&gt;}
    • 有没有办法(例如genereics)提供关于应该发生什么重试的异常(可恢复)?不要重试致命错误。
    • 我猜你可以使用catch(Exception e) {,那么任何不可恢复的java.lang.Error(或子类)都不会被捕获,并且会立即退出。
    • 如何将参数传递给errorProneOperation函数?我试过你的代码,但在第二次和进一步的尝试中传递给函数的参数是空的(我正在传递地图)?
    【解决方案2】:

    我可以建议模仿一下(我不确定retry 的语义):

    def retry(handler, c) {
        try {
            c()
        } catch(e) {
            handler(e)
            retry(handler, c)  // restart from beginning
        }
    }
    
    def handler = {e ->
        // handles error
    }
    
    retry(handler) {
        do_something // exception raised
    }
    

    【讨论】:

      【解决方案3】:

      现在人们会建议您使用ScheduledExecutorService 来实现这种try-catch-retry 功能,因为Thread.sleep() 被认为已过时并且可能对性能不利。我打算通过 cletus 为您指出一个很好的答案,但我一生都找不到它。如果我可以挖掘它,我会更新我的答案。

      编辑: 找到它:How to retry function request after a certain time 希望这对您有所帮助。

      【讨论】:

        猜你喜欢
        • 2015-08-08
        • 2012-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-31
        • 1970-01-01
        相关资源
        最近更新 更多