ThrowableUtils { public static Throwable getRootCause(Throwable throwable) { if (throwable.getCause() == null) { return throwable; } Throwable cause; while ((cause = throwable.getCause()) != null) { throwable = cause; } return throwable; }  static Throwable getRootCause(Throwable throwable); static boolean hasCauseType(Throwable throwable, Class<? extends Throwable> causeClass); static boolean hasCauseMessage(Throwable throwable, String message); static void setRootCause(Throwable exception, Throwable newRootCause);  }
@Test public void getRootCauseOfNullShouldThrowNullPointerException() { Throwable thrown = catchThrowable(() -> getRootCause(null)); assertThat(thrown).isExactlyInstanceOf(NullPointerException.class); }
@Test public void getRootCauseOfLeafExceptionShouldReturnSameInstance() { Throwable exception = new Exception(); Throwable rootCause = getRootCause(exception); assertThat(rootCause).isSameAs(exception); }
@Test public void getRootCauseOfExceptionShouldReturnCause() { Throwable cause = new Exception(); Throwable rootCause = getRootCause(new Exception(cause)); assertThat(rootCause).isSameAs(cause); }
@Test public void getRootCauseOfExceptionTreeShouldReturnCause() { Throwable cause = new Exception(); Throwable rootCause = getRootCause(new Exception(new Exception(cause))); assertThat(rootCause).isSameAs(cause); }
@Test public void getRootCauseOfErrorTreeShouldReturnCause() { Throwable cause = new Error(); Throwable rootCause = getRootCause(new Error(new Error(cause))); assertThat(rootCause).isSameAs(cause); }