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