2017-07-21 154 views
1

我必须做一个函数调用。如果失败,我再试2次。如果它在2次重试后仍然失败,我会抛出异常。如何使用try catch重试机制为for循环编写更短,更高效的代码?

下面是它的工作我当前的代码:

for (int retry = 0; retry < 4; retry++) { 
     try { 
      callFunction(); 
      break; 
     } catch (Exception e) { 
      if (retry >= 0 && retry < 3) { 
       warn("callFunction failed. Retrying.." +(retry+1)); 
      } else { 
       warn("Retried maximum number of "+(retry+1)+" times. Failing the script"); 
       e.printStackTrace(); 
      } 
     } 
    } 

OUTPUT:

callFunction failed. Retrying..1 
callFunction failed. Retrying..2 
callFunction failed. Retrying..3 
Retried maximum number of 4 times. Failing the script 

我明白,这是不是即使它正在编写的最有效方式。你能帮我重构一下这段代码,以符合Java干净代码的最佳实践标准吗?

+1

我投票结束这个问题作为题外话,因为它属于[codereview.se]。 – shmosel

+1

另请阅读[tag:coding-style]标签的说明。 – shmosel

回答

4

什么是没有那么大的位置:

  • 深嵌套
  • 冗余retry >= 0条件
  • 反复(retry + 1)
  • 重复使用的幻数的4

我想在这里,while环路可能会更自然地流动, 并在最后检查重试计数。

int maxRetries = 3; 
int retry = 0; 
Exception thrown = null; 

while (retry < maxRetries) { 
    try { 
    callFunction(); 
    break; 
    } catch (Exception e) { 
    thrown = e; 
    retry++; 
    warn("callFunction failed. Retrying.." + retry); 
    } 
} 

if (retry == maxRetries) { 
    warn("reached max"); 
    thrown.printStackTrace(); 
} 

其实,如果你把它变成一个函数就更好了。 将会有更少的变量:

void executeWithRetries(int maxRetries) { 
    Exception thrown = null; 

    for (int retry = 0; retry < maxRetries; retry++) { 
    try { 
     callFunction(); 
     return; 
    } catch (Exception e) { 
     thrown = e; 
     warn("callFunction failed. Retrying.." + retry); 
    } 
    } 

    warn("reached max"); 
    thrown.printStackTrace(); 
} 
+0

这有帮助。但是,当我尝试在if(retry == maxRetries)块中打印异常的堆栈跟踪时,变量'e'超出了范围。 '如果(重试== MAX_RETRY_COUNT){ \t \t警告( “达到重试的最大次数失败脚本。”); \t \t e.printStackTrace(); \t \t}' – InsecureNoob

+0

@InsecureNoob啊是的。你可以将它保存在一个变量中(更新我的答案)。 – janos

+0

这个工程!谢谢! – InsecureNoob

0

另一种方法是使用一个库这样的事情。使用Failsafe

RetryPolicy retryPolicy = new RetryPolicy().withMaxRetries(3); 
Failsafe.with(retryPolicy) 
    .onRetry((c, f, ctx) -> warn("callFunction failed. Retrying.." + ctx.getExecutions())) 
    .onFailure(e -> { 
    warn("Retried maximum number of times. Failing the script"); 
    e.printStackTrace(); 
    }); 
    .run(this::callFunction);