用Java编写带有清除操作的catch块
作者:互联网
我找不到关于Java中catch块的任何建议,这些建议涉及一些清除操作,这些清除操作本身可能会引发异常.
经典的示例是stream.close()的示例,通常在finally子句中调用它,如果抛出异常,我们可以通过在try-catch块中调用它来忽略它,或者声明它被重新抛出.
但总的来说,我该如何处理以下情况:
public void doIt() throws ApiException { //ApiException is my "higher level" exception
try {
doLower();
} catch(Exception le) {
doCleanup(); //this throws exception too which I can't communicate to caller
throw new ApiException(le);
}
}
我可以做:
catch(Exception le) {
try {
doCleanup();
} catch(Exception le1) {
//ignore?
//log?
}
throw new ApiException(le); //I must throw le
}
但这意味着我将必须进行一些日志分析以了解清理失败的原因.
如果我这样做了:
catch(Exception le) {
try {
doCleanup();
} catch(Exception le1) {
throw new ApiException(le1);
}
结果导致丢失了将我带到第一拳的陷阱区的文件.
人们在这里使用哪些成语?
>在throws子句中声明较低级别的异常?
>清除操作期间是否忽略异常?
解决方法:
首先,确定您是否真的需要从finally块中抛出-请仔细考虑-在close()调用失败的情况下…好吧,记录下来就可以了-但是您的API的更高层真正可以做什么关于这个问题?因此,对于99%的情况,您将记录辅助数据库,然后重新抛出主数据库.
接下来,如果您确实需要抛出第二个异常,请确定导致第二个异常的各种原因是否重要.他们是很少见的.因此,将次要原因设置为主要原因(使用适当的构造函数或initCause()).
最后,如果必须抛出辅助节点,并保留辅助节点和主节点的完整堆栈跟踪,那么您将创建一个自定义Exception来处理这种情况.这很丑陋,因为您可能想从不同的父类派生.如果确实出现这种情况,我建议创建一个辅助类,该类能够填充目标异常的堆栈跟踪,从而根据两个异常生成有意义的跟踪(请确保对第二个异常使用缩进,因此嵌套的异常是容易拉开).
但大多数情况下,我建议您使用对数和重新抛出原语范式.专注于解决主要问题,次要问题通常会自行解决(这里的经典示例是IO异常,它使事情变得如此糟糕,以至于close()的调用也无法成功).
标签:exception,exception-handling,java 来源: https://codeday.me/bug/20191210/2099032.html