一些第3方库吞没了一个异常(exception):
String getAnswer(){
try{
// do stuff, modify instance state, maybe throw some exceptions
// ...
return computeAnswer();
}catch (SomeException e){
return null;
}
}
我想将其更改为:
String getAnswer() throws SomeException{
// do stuff, modify instance state, maybe throw some exceptions
// ...
return computeAnswer();
}
我不能,因为该库已经打包到jar中了。那么,有没有办法将异常带回来?
我不需要抛出,带有异常和消息的stacktrace也会起作用。
我认为反射可能对这里没有帮助,也许是
Unsafe
?是的,我知道我可以使用调试器来了解正在发生的事情,但是如果我在运行时需要异常来记录日志以及诸如之类的东西,那将不会很有用。
最佳答案
您可以在不进行反射或AOP的情况下进行操作。 的主要思想是在SomeException
的构造函数中引发另一个(未经检查的)异常。有一些限制(请参阅此答案的结尾),但我希望它能满足您的需求。
您需要将SomeException
替换为新版本(只需在原始包中但在src目录中创建SomeException.java文件),例如:
package com.3rdpartylibrary;
public class SomeException extends Exception {
public static class SomeExceptionWrapperException extends RuntimeException {
public SomeExceptionWrapperException(final SomeException ex) {
super(ex.getMessage(), ex);
}
}
public SomeException(final String message) {
super(message);
throw new SomeExceptionWrapperException(this); //<=== the key is here
}
}
必须取消选中
SomeExceptionWrapperException
(继承自RuntimeException或Error)。这将是我们包装丑陋的第三方SomeException
上的catch(...)
的工具然后,您可以在代码中捕获
SomeExceptionWrapperException
(并最终将原始的SomeException抛出://original, unmodifiable 3rdParty code, here as a example
public String getAnswer() {
try {
//some code
throw new SomeException("a message");
} catch (final SomeException e) {
return null;
}
}
//a wrapper to getAnswer to unwrapp the `SomeException`
public String getAnswerWrapped() throws SomeException {
try {
return getAnswer();
} catch (final SomeExceptionWrapperException e) {
throw (SomeException) e.getCause();
}
}
@Test(expected = SomeException.class)
public void testThrow() throws SomeException {
final String t = getAnswerWrapped();
}
测试将变为绿色,因为将抛出原始
SomeException
。局限性:
如果以下任何一种,此解决方案将不起作用:
SomeException
在java.lang
中),因为您不能替换java.lang
类(或参见Replacing java class?)catch(Throwable e)
(这将是可怕的,并会促使您忽略完整的3rd方库))关于java - 抢救Java中的吞咽异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32358652/