public static Optional<Throwable> findThrowableInChain(Predicate<Throwable> condition, @Nullable Throwable t) {
        final Set<Throwable> seen = new HashSet<>();
        while (t != null && !seen.contains(t)) {
            if (condition.test(t)) {
                return Optional.of(t);
            }
            seen.add(t);
            t = t.getCause();
        }
        return Optional.empty();
    }
@Test
    void findsChainedException() {
        final RuntimeException first = new RuntimeException("first");
        final RuntimeException second = new RuntimeException("second", first);
        final RuntimeException third = new RuntimeException("third", second);

        assertThat(findThrowableInChain(t -> "third".equals(t.getMessage()), third)).contains(third);
        assertThat(findThrowableInChain(t -> "second".equals(t.getMessage()), third)).contains(second);
        assertThat(findThrowableInChain(t -> "first".equals(t.getMessage()), third)).contains(first);
        assertThat(findThrowableInChain(t -> false, third)).isEmpty();
    }