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

时间:2017-11-08 00:52:48

标签: java exception-handling

我正在尝试针对几个不同的服务器执行相同的任务。如果其中一个呼叫成功,则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”类型抛出,而不是像原来的类型那样抛弃它。这可能吗?

1 个答案:

答案 0 :(得分:1)

如果是"原来的例外"你的意思是第一个例外,你这样做。

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为false但未发生错误。

当然,将throws Exception添加到方法中,因此它会编译。

<强>更新

现在,如果doSomethingToServer()抛出已检查的异常,并且您希望doSomething()抛出相同的已检查异常,而不是全面覆盖全部Exception,那么您像以前一样捕获异常,但在重新抛出它时必须转换为适当的异常。

为了帮助保持演员陈述与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
}