Try-catch是用来帮助异常处理的。这意味着它将在某种程度上帮助我们的系统变得更加健壮:尝试从意外事件中恢复。

我们怀疑在执行和指令(发送消息)时可能会发生一些事情,因此它被包含在try中。如果发生了几乎意想不到的事情,我们可以做些什么:我们编写捕获。我不认为我们调用只是为了记录异常。我认为catch块是为了给我们从错误中恢复的机会。

现在,假设我们从错误中恢复,因为我们可以修复错误。如果能再试一次,那就太好了:

try{ some_instruction(); }
catch (NearlyUnexpectedException e){
   fix_the_problem();
   retry;
}

这将很快陷入永恒循环,但让我们假设fix_the_problem返回true,然后重试。假设在Java中没有这样的东西,你将如何解决这个问题?你认为解决这个问题的最佳设计代码是什么?

这就像一个哲学问题,因为我已经知道Java不直接支持我所要求的内容。


当前回答

其余解决方案的问题是,对应的函数在没有时间间隔的情况下连续尝试,从而溢出堆栈。

为什么不一刻不停地尝试呢?

这里有一个使用setTimeout和递归函数的解决方案:

(function(){ try{ Run(); //tries for the 1st time, but Run() as function is not yet defined } catch(e){ (function retry(){ setTimeout(function(){ try{ console.log("trying..."); Run(); console.log("success!"); } catch(e){ retry(); //calls recursively } }, 1000); //tries every second }()); } })(); //after 5 seconds, defines Run as a global function var Run; setTimeout(function(){ Run = function(){}; }, 5000);

将函数Run()替换为希望每秒重试的函数或代码。

其他回答

强制性的“企业级”解决方案:

public abstract class Operation {
    abstract public void doIt();
    public void handleException(Exception cause) {
        //default impl: do nothing, log the exception, etc.
    }
}

public class OperationHelper {
    public static void doWithRetry(int maxAttempts, Operation operation) {
        for (int count = 0; count < maxAttempts; count++) {
            try {
                operation.doIt();
                count = maxAttempts; //don't retry
            } catch (Exception e) {
                operation.handleException(e);
            }
        }
    }
}

并呼吁:

OperationHelper.doWithRetry(5, new Operation() {
    @Override public void doIt() {
        //do some stuff
    }
    @Override public void handleException(Exception cause) {
        //recover from the Exception
    }
});

你需要像这样在while循环中封装try-catch: -

int count = 0;
int maxTries = 3;
while(true) {
    try {
        // Some Code
        // break out of loop, or return, on success
    } catch (SomeException e) {
        // handle exception
        if (++count == maxTries) throw e;
    }
}

我已经采取了count和maxTries,以避免运行到一个无限循环,以防异常继续发生在你的try块。

这些答案基本上都是一样的。我的也是,但我喜欢这种形式

boolean completed = false;
Throwable lastException = null;
for (int tryCount=0; tryCount < config.MAX_SOME_OPERATION_RETRIES; tryCount++)
{
    try {
        completed = some_operation();
        break;
    }
    catch (UnlikelyException e) {
        lastException = e;
        fix_the_problem();
    }
}
if (!completed) {
    reportError(lastException);
}

你可以从jcabi-aspect(我是一名开发人员)使用AOP和Java注释:

@RetryOnFailure(attempts = 3, delay = 5)
public String load(URL url) {
  return url.openConnection().getContent();
}

您还可以使用@Loggable和@LogException注释。

Try-Catch所做的就是允许程序优雅地失败。在catch语句中,通常尝试记录错误,如果需要,可能还会回滚更改。

bool finished = false;

while(finished == false)
{
    try
    {
        //your code here
        finished = true
    }
    catch(exception ex)
    {
        log.error("there was an error, ex");
    }
}