一些第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

局限性:

如果以下任何一种,此解决方案将不起作用:
  • (如果SomeExceptionjava.lang中),因为您不能替换java.lang类(或参见Replacing java class?)
  • (如果第3方方法具有catch(Throwable e)(这将是可怕的,并会促使您忽略完整的3rd方库))
  • 关于java - 抢救Java中的吞咽异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32358652/

    10-12 05:06