2011-08-17 20 views
12

異常在Ruby後,我可以這樣寫:重試在Groovy

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

是否有在Groovy/Java的類似的東西?

我發現this但也許有更好的?

回答

12

你可以建立在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() 
} 
+1

現在,如果'IllegalStateException'將使用一個例外(第一最後很難說?)作爲它的原因,它會更**更有用,因爲你可以看到**爲什麼**它失敗了。在生產中,我不希望每次嘗試失敗都要打印一個堆棧跟蹤。如果所有重試失敗,我只想知道它。 –

+0

感謝約阿希姆 - 關於我在收集個別例外時的建議。至於不想要堆棧跟蹤 - 當然,這只是爲了說明這一點。由於異常現在正在收集到最後報告,可能errorHandler的目的是在'body.call()'重試之前重置所需的任何資源 - 在這種情況下,默認的閉包可能只是'{ - >} ' – winstaan74

+0

我結束了使用非常相似的東西。感謝winstaan​​。 –

1

現在人們會建議您使用ScheduledExecutorService來實現這種try-catch-retry功能,因爲Thread.sleep()被認爲過時並且可能對性能不利。我想通過cletus向你指出一個很好的答案,但不能在我的生活中找到它。如果我可以挖掘它,我會更新我的答案。

編輯:找到它:How to retry function request after a certain time希望這對你有一些幫助。

1

我可以建議效仿還挺相同的(我不知道有關的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 
}