首页 > 解决方案 > 在所有内部异常上查找特定类型的自定义异常

问题描述

我正在尝试从特定实例类型的顶级异常中递归查找所有内部异常(getCause)。

public class MyCustomRunTimeException extends RuntimeException {

    public MyCustomRunTimeException() {
    }

    public MyCustomRunTimeException(Exception innerException) {
        super(innerException);
    }
}

这是我尝试过的:

和我早期的“查找”方法:

private void findAllSpecificTypeOfInnerExceptions(Exception ex)
{

            Collection<MyCustomRunTimeException> MyCustomRunTimeExceptions = Stream.iterate(ex, Throwable::getCause)
                    .filter(element ->
                            element != null
                                    && element instanceof MyCustomRunTimeException
                    )
                    .map(obj -> (MyCustomRunTimeException) obj)
                    .collect(Collectors.toList());

}

它不工作。:(我已经尝试了其他几件事(尚未显示)......如果我得到任何不引发异常的东西,我会将它们作为“附加”发布到这个问题。不工作......我是获取 NullPointers 异常和(取决于我的调整)java.lang.reflect.InvocationTargetException 异常。

以下是一些可以找到 1:N“匹配项”的示例。

    Exception exampleOne = new MyCustomRunTimeException();

    Exception exampleTwo = new Exception(new MyCustomRunTimeException());

    Exception exampleThree =new Exception(new Exception(new MyCustomRunTimeException()));

    Exception exampleFour =new Exception(new Exception(new MyCustomRunTimeException(new ArithmeticException())));

标签: javajava-8

解决方案


This is a case where I really think it's easiest doing the recursive bit in a loop, rather than using streams entirely:

List<Throwable> exlist = new ArrayList<>();
while(ex.getCause()!=null) {
    exlist.add(ex.getCause());
    ex = ex.getCause();
}
exlist = exlist.stream().filter(e -> e instanceof MyCustomRunTimeException).collect(Collectors.toList());

There are better options in Java 9+, and if you use external libraries, but not really in core Java 8 (hacks do exist, but that makes it much less clear than the above, IMHO, and I really don't see that it's worth introducing an external library just for this purpose.)

Or this variation:

private <T extends Throwable> Collection<T> aggregateSubClassExceptions(Throwable inputEx, Class<T> type) {

    Collection<T> returnItems = new ArrayList<>();
    Throwable exc = inputEx;
    while (exc != null) {
        if (type.isInstance(exc)) {
            returnItems.add(type.cast(exc));
        }
        exc = exc.getCause();
    }

    return returnItems;
}

This code was getting the specific type AND any subclasses:

    Collection<MyCustomRunTimeException> testItOutCollection;



    Exception exampleOne = new MyCustomRunTimeException();
    Exception exampleTwo = new Exception(new MyCustomRunTimeException());
    Exception exampleThree = new Exception(new Exception(new MyCustomRunTimeException()));
    Exception exampleFour = new Exception(new Exception(new MyCustomRunTimeException(new ArithmeticException())));
    MyCustomRunTimeException exampleFive = new MyCustomRunTimeException(new MySubMyCustomRunTimeException(new MyCustomRunTimeException(new ArithmeticException())));

    testItOutCollection = this.aggregateSubClassExceptions(exampleOne, MyCustomRunTimeException.class);
    testItOutCollection = this.aggregateSubClassExceptions(exampleTwo, MyCustomRunTimeException.class);
    testItOutCollection = this.aggregateSubClassExceptions(exampleThree, MyCustomRunTimeException.class);
    testItOutCollection = this.aggregateSubClassExceptions(exampleFour, MyCustomRunTimeException.class);
    testItOutCollection = this.aggregateSubClassExceptions(exampleFive, MyCustomRunTimeException.class);

推荐阅读