如何使用 try catch 重试机制为 for 循环编写更短、更高效的代码?

How to write a shorter and more efficient code for a for loop with try catch retry mechanism?

我必须进行函数调用。如果失败,我再重试 2 次。如果2次重试后仍然失败,我抛出一个异常。

下面是我当前正在运行的代码:

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();
            }
        }
    }

输出:

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

我知道这不是最有效的编码方式,尽管它可以工作。你能帮我重构这段代码以满足 Java 干净代码的最佳实践标准吗?

这里有什么不太好:

  • 深度嵌套
  • 多余的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();
}

另一种选择是使用库来完成类似的事情。使用 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);