tom*_*136 15 java exception-handling exception
一些第三方图书馆吞下了一个例外:
String getAnswer(){
try{
// do stuff, modify instance state, maybe throw some exceptions
// ...
return computeAnswer();
}catch (SomeException e){
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我想把它改成:
String getAnswer() throws SomeException{
// do stuff, modify instance state, maybe throw some exceptions
// ...
return computeAnswer();
}
Run Code Online (Sandbox Code Playgroud)
我不能,因为库已经打包成一个罐子.那么,有没有办法将异常带回来?
我不需要重新抛出,带有异常的堆栈跟踪和消息也可以工作.
我不认为这里的反思会有所帮助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
}
}
Run Code Online (Sandbox Code Playgroud)
必须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();
}
Run Code Online (Sandbox Code Playgroud)
测试将像原始测试一样呈绿色SomeException,并将被抛出。
限制:
如果出现以下情况,此解决方案将不起作用:
SomeException是java.lang因为你不能替换java.lang类(或者参见替换 java 类?)catch(Throwable e)(这将是可怕的,并且应该促使您忽略完整的第 3 方库)