检查某个exception类型是否是嵌套exception中的原因(原因等等)的最佳方法?
我正在编写一些JUnit测试,以validation是否抛出了类型MyCustomException
的exception。 但是,此exception多次包含在其他exception中,例如InvocationTargetException,而InvocationTargetException又包含在RuntimeException中。
什么是确定MyCustomException是否以某种方式导致我实际捕获的exception的最佳方法? 我想做这样的事情(见下划线):
try { doSomethingPotentiallyExceptional(); fail("Expected an exception."); } catch (RuntimeException e) { if (!e.
try { doSomethingPotentiallyExceptional(); fail("Expected an exception."); } catch (RuntimeException e) { if (!e.
e.wasCausedBy(MyCustomException.class) fail("Expected a different kind of exception."); }
(MyCustomException.class) fail("Expected a different kind of exception."); }
我想避免调用getCause()
一些“层”深层,以及类似的丑陋的解决方法。 有更好的方式吗?
(显然,Spring有NestedRuntimeException.contains(Class) ,它可以做我想要的 – 但我没有使用Spring。)
关闭:好的,我想有一个实用方法真的没有绕过:-)感谢所有回复的人!
你为什么要避免使用getCause
。 当然,您可以自己编写一个执行任务的方法,例如:
public static boolean isCause( Class extends Throwable> expected, Throwable exc ) { return expected.isInstance(exc) || ( exc != null && isCause(expected, exc.getCause()) ); }
如果您使用的是Apache Commons Lang ,那么您可以使用以下内容:
(1)当原因完全符合指定类型时
if (ExceptionUtils.indexOfThrowable(exception, ExpectedException.class) != -1) { // exception is or has a cause of type ExpectedException.class }
(2)当cause应该是指定类型或其子类类型时
if (ExceptionUtils.indexOfType(exception, ExpectedException.class) != -1) { // exception is or has a cause of type ExpectedException.class or its subclass }
我认为除了通过getCause图层调用之外你别无选择。 如果你看一下Spring NestedRuntimeException的源代码,你提到它是如何实现的。
模仿是最真诚的奉承forms。 基于对源的快速检查 ,这正是NestedRuntimeException的作用:
/** * Check whether this exception contains an exception of the given type: * either it is of the given class itself or it contains a nested cause * of the given type. * @param exType the exception type to look for * @return whether there is a nested exception of the specified type */ public boolean contains(Class exType) { if (exType == null) { return false; } if (exType.isInstance(this)) { return true; } Throwable cause = getCause(); if (cause == this) { return false; } if (cause instanceof NestedRuntimeException) { return ((NestedRuntimeException) cause).contains(exType); } else { while (cause != null) { if (exType.isInstance(cause)) { return true; } if (cause.getCause() == cause) { break; } cause = cause.getCause(); } return false; } }
CAVEAT :以上是截至2009年3月4日的代码,所以,如果你真的想知道Spring现在在做什么,你应该研究现在存在的代码(无论何时)。
好吧,我认为没有调用getCause()
就没有办法做到这一点。 你认为这样做很难实现一个实用程序类:
public class ExceptionUtils { public static boolean wasCausedBy(Throwable e, Class extends Throwable>) { // call getCause() until it returns null or finds the exception } }
你可以用番石榴做到这一点:
FluentIterable.from(Throwables.getCausalChain(e)) .filter(Predicates.instanceOf(ConstraintViolationException.class)) .first() .isPresent();
基于Patrick Boos回答:如果您使用Apache Commons Lang 3,您可以检查:
indexOfThrowable :返回与exception链中指定类( 确切 )匹配的第一个Throwable的(从零开始)索引。 指定类的子类不匹配
if (ExceptionUtils.indexOfThrowable(e, clazz) != -1) { // your code }
要么
indexOfType :返回与例外链中指定的类或子类匹配的第一个Throwable的(从零开始)索引。 指定类的子类匹配
if (ExceptionUtils.indexOfType(e, clazz) != -1) { // your code }
Java 8的多个类型的示例:
Class extends Throwable>[] classes = {...} boolean match = Arrays.stream(classes) .anyMatch(clazz -> ExceptionUtils.indexOfType(e, clazz) != -1);
- 如何在我的自定义exception中设置我自己的消息,可以检索我的getMessage()但是没有使用构造函数,有什么办法吗?
- 抛出的Java抽象类
- Java:BufferedReader的readLine()中的IOEXceptions是什么?
- 小程序。 java.lang.reflect.InvocationTargetException
- 在预期时处理NumberFormatException的正确方法是什么?
- 当方法签名不允许抛出exception时,如何抛出exception?
- java同步和exception处理
- 调试时强制exception
- 如何使用Intellij Idea的exception断点