抛出一个通用的 Exception 作为原始异常类型

Throwing a generic Exception as the original exception type

我正在尝试对几个不同的服务器执行相同的任务。如果其中一个调用成功,则 who 任务应该成功。但是,如果每次调用都失败,我想抛出最新抛出的异常(因为它可能与其他异常相同)。这可能吗?

这是我正在使用的内容:

public void doSomething()
{
  boolean success = false;
  Exception failureException;

  for(Server server : Servers.values())
  {
    try{
      doSomethingToServer(server);
      success = true;
    }
    catch(Exception e){
      failureException = e;
      log("failure reason");
    }
  }

  if(!success){
    //throw failureException as its original type
  }
}

与其将原始异常作为 "Exception" 类型抛出,不如将其作为最初的类型抛出。这可能吗?

如果 "the original exception" 你的意思是 第一个 异常,你可以这样做。

public void doSomething() throws Exception {
    boolean success = false;
    Exception failureException = null;
    for (Server server : Servers.values()) {
        try {
            doSomethingToServer(server);
            success = true;
        } catch (Exception e) {
            if (failureException == null)
                failureException = e;
            else
                failureException.addSuppressed(e);
        }
    }
    if (! success && failureException != null)
        throw failureException;
}

添加代码以添加次要异常作为 suppressed exceptions,并在 Servers 为空的情况下进行空检查,即 success 为假但未发生错误。

并且当然添加了 throws Exception 到方法中,所以它编译。


更新

现在,如果 doSomethingToServer() 抛出已检查异常,并且您希望 doSomething() 抛出相同的已检查异常,而不是一揽子包罗万象 Exception,然后你像以前一样捕获异常,但是在重新抛出它时必须转换为适当的异常。

为了帮助 cast 语句与 doSomethingToServer() 实际抛出的内容保持同步,最好将 catch 子句更改为更明确。这样,如果有人添加新的已检查异常,他们 必须 修改 catch 子句,并且希望这能触发他们记住添加新的 if-then-cast 语句。

public void doSomething() throws IOException, GeneralSecurityException {
    boolean success = false;
    Exception failureException = null;
    for (Server server : Servers.values()) {
        try {
            doSomethingToServer(server);
            success = true;
        } catch (RuntimeException | IOException | GeneralSecurityException e) {
            if (failureException == null)
                failureException = e;
            else
                failureException.addSuppressed(e);
        }
    }
    if (! success && failureException != null) {
        if (failureException instanceof RuntimeException)
            throw (RuntimeException) failureException;
        if (failureException instanceof IOException)
            throw (IOException) failureException;
        if (failureException instanceof GeneralSecurityException)
            throw (GeneralSecurityException) failureException;
        throw new RuntimeException("Oops! Unexpected exception type: " + failureException, failureException);
    }
}

private void doSomethingToServer(Server server) throws IOException, GeneralSecurityException {
    // code here
}