1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.exception;
18
19 import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNotSame;
25 import static org.junit.jupiter.api.Assertions.assertNull;
26 import static org.junit.jupiter.api.Assertions.assertSame;
27 import static org.junit.jupiter.api.Assertions.assertThrows;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29
30 import java.io.ByteArrayOutputStream;
31 import java.io.IOException;
32 import java.io.PrintStream;
33 import java.io.PrintWriter;
34 import java.io.StringWriter;
35 import java.lang.reflect.Constructor;
36 import java.lang.reflect.Modifier;
37 import java.util.ArrayList;
38 import java.util.List;
39 import java.util.stream.Collectors;
40
41 import org.apache.commons.lang3.AbstractLangTest;
42 import org.apache.commons.lang3.test.NotVisibleExceptionFactory;
43 import org.junit.jupiter.api.AfterEach;
44 import org.junit.jupiter.api.BeforeEach;
45 import org.junit.jupiter.api.Test;
46
47
48
49
50 class ExceptionUtilsTest extends AbstractLangTest {
51
52
53
54
55
56
57 private static final class ExceptionWithCause extends Exception {
58 private static final long serialVersionUID = 1L;
59
60 private Throwable cause;
61
62 ExceptionWithCause(final String str, final Throwable cause) {
63 super(str);
64 setCause(cause);
65 }
66
67 ExceptionWithCause(final Throwable cause) {
68 setCause(cause);
69 }
70
71 @Override
72 public synchronized Throwable getCause() {
73 return cause;
74 }
75
76 public void setCause(final Throwable cause) {
77 this.cause = cause;
78 }
79 }
80
81
82
83
84
85
86 private static final class ExceptionWithoutCause extends Exception {
87 private static final long serialVersionUID = 1L;
88
89 @SuppressWarnings("unused")
90 public void getTargetException() {
91
92 }
93 }
94
95
96
97 private static final class NestableException extends Exception {
98 private static final long serialVersionUID = 1L;
99
100 @SuppressWarnings("unused")
101 NestableException() {
102 }
103
104 NestableException(final Throwable t) {
105 super(t);
106 }
107 }
108
109 public static class TestThrowable extends Throwable {
110 private static final long serialVersionUID = 1L;
111 }
112
113 private static int redeclareCheckedException() {
114 return throwsCheckedException();
115 }
116
117 private static int throwsCheckedException() {
118 try {
119 throw new IOException();
120 } catch (final Exception e) {
121 ExceptionUtils.asRuntimeException(e);
122 return -1;
123 }
124 }
125
126 private ExceptionWithCause cyclicCause;
127
128 private Throwable jdkNoCause;
129
130 private NestableException nested;
131
132 private Throwable notVisibleException;
133
134 private Throwable withCause;
135
136 private Throwable withoutCause;
137
138 private Throwable createExceptionWithCause() {
139 try {
140 try {
141 throw new ExceptionWithCause(createExceptionWithoutCause());
142 } catch (final Throwable t) {
143 throw new ExceptionWithCause(t);
144 }
145 } catch (final Throwable t) {
146 return t;
147 }
148 }
149
150 private Throwable createExceptionWithoutCause() {
151 try {
152 throw new ExceptionWithoutCause();
153 } catch (final Throwable t) {
154 return t;
155 }
156 }
157
158 @BeforeEach
159 public void setUp() {
160 withoutCause = createExceptionWithoutCause();
161 nested = new NestableException(withoutCause);
162 withCause = new ExceptionWithCause(nested);
163 jdkNoCause = new NullPointerException();
164 final ExceptionWithCause a = new ExceptionWithCause(null);
165 final ExceptionWithCause b = new ExceptionWithCause(a);
166 a.setCause(b);
167 cyclicCause = new ExceptionWithCause(a);
168 notVisibleException = NotVisibleExceptionFactory.createException(withoutCause);
169 }
170
171 @AfterEach
172 public void tearDown() {
173 withoutCause = null;
174 nested = null;
175 withCause = null;
176 jdkNoCause = null;
177 cyclicCause = null;
178 notVisibleException = null;
179 }
180
181 @Test
182 void test_getMessage_Throwable() {
183 Throwable th = null;
184 assertEquals("", ExceptionUtils.getMessage(th));
185
186 th = new IllegalArgumentException("Base");
187 assertEquals("IllegalArgumentException: Base", ExceptionUtils.getMessage(th));
188
189 th = new ExceptionWithCause("Wrapper", th);
190 assertEquals("ExceptionUtilsTest.ExceptionWithCause: Wrapper", ExceptionUtils.getMessage(th));
191 }
192
193 @Test
194 void test_getRootCauseMessage_Throwable() {
195 Throwable th = null;
196 assertEquals("", ExceptionUtils.getRootCauseMessage(th));
197
198 th = new IllegalArgumentException("Base");
199 assertEquals("IllegalArgumentException: Base", ExceptionUtils.getRootCauseMessage(th));
200
201 th = new ExceptionWithCause("Wrapper", th);
202 assertEquals("IllegalArgumentException: Base", ExceptionUtils.getRootCauseMessage(th));
203 }
204
205 @Test
206 void testAsRuntimeException() {
207 final Exception expected = new InterruptedException();
208 assertSame(expected, assertThrows(Exception.class, () -> ExceptionUtils.asRuntimeException(expected)));
209 assertNotSame(expected, assertThrows(Exception.class, () -> ExceptionUtils.asRuntimeException(new InterruptedException())));
210
211 assertThrows(expected.getClass(), () -> {
212 @SuppressWarnings("unused")
213 final Object retVal = ExceptionUtils.asRuntimeException(expected);
214 });
215
216 assertThrows(expected.getClass(), () -> {
217 @SuppressWarnings("unused")
218 final RuntimeException retVal = ExceptionUtils.asRuntimeException(expected);
219 });
220
221 assertThrows(expected.getClass(), () -> {
222 @SuppressWarnings("unused")
223 final IllegalStateException retVal = ExceptionUtils.asRuntimeException(expected);
224 });
225 }
226
227 @Test
228 void testCatchTechniques() {
229 IOException ioe = assertThrows(IOException.class, ExceptionUtilsTest::throwsCheckedException);
230 assertEquals(1, ExceptionUtils.getThrowableCount(ioe));
231
232 ioe = assertThrows(IOException.class, ExceptionUtilsTest::redeclareCheckedException);
233 assertEquals(1, ExceptionUtils.getThrowableCount(ioe));
234 }
235
236 @Test
237 void testConstructor() {
238 assertNotNull(new ExceptionUtils());
239 final Constructor<?>[] cons = ExceptionUtils.class.getDeclaredConstructors();
240 assertEquals(1, cons.length);
241 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
242 assertTrue(Modifier.isPublic(ExceptionUtils.class.getModifiers()));
243 assertFalse(Modifier.isFinal(ExceptionUtils.class.getModifiers()));
244 }
245
246 @Test
247 void testForEach_jdkNoCause() {
248 final List<Throwable> throwables = new ArrayList<>();
249 ExceptionUtils.forEach(jdkNoCause, throwables::add);
250 assertEquals(1, throwables.size());
251 assertSame(jdkNoCause, throwables.get(0));
252 }
253
254 @Test
255 void testForEach_nested() {
256 final List<Throwable> throwables = new ArrayList<>();
257 ExceptionUtils.forEach(nested, throwables::add);
258 assertEquals(2, throwables.size());
259 assertSame(nested, throwables.get(0));
260 assertSame(withoutCause, throwables.get(1));
261 }
262
263 @Test
264 void testForEach_null() {
265 final List<Throwable> throwables = new ArrayList<>();
266 ExceptionUtils.forEach(null, throwables::add);
267 assertEquals(0, throwables.size());
268 }
269
270 @Test
271 void testForEach_recursiveCause() {
272 final List<Throwable> throwables = new ArrayList<>();
273 ExceptionUtils.forEach(cyclicCause, throwables::add);
274 assertEquals(3, throwables.size());
275 assertSame(cyclicCause, throwables.get(0));
276 assertSame(cyclicCause.getCause(), throwables.get(1));
277 assertSame(cyclicCause.getCause().getCause(), throwables.get(2));
278 }
279
280 @Test
281 void testForEach_withCause() {
282 final List<Throwable> throwables = new ArrayList<>();
283 ExceptionUtils.forEach(withCause, throwables::add);
284 assertEquals(3, throwables.size());
285 assertSame(withCause, throwables.get(0));
286 assertSame(nested, throwables.get(1));
287 assertSame(withoutCause, throwables.get(2));
288 }
289
290 @Test
291 void testForEach_withoutCause() {
292 final List<Throwable> throwables = new ArrayList<>();
293 ExceptionUtils.forEach(withoutCause, throwables::add);
294 assertEquals(1, throwables.size());
295 assertSame(withoutCause, throwables.get(0));
296 }
297
298 @SuppressWarnings("deprecation")
299 @Test
300 void testGetCause_Throwable() {
301 assertSame(null, ExceptionUtils.getCause(null));
302 assertSame(null, ExceptionUtils.getCause(withoutCause));
303 assertSame(withoutCause, ExceptionUtils.getCause(nested));
304 assertSame(nested, ExceptionUtils.getCause(withCause));
305 assertSame(null, ExceptionUtils.getCause(jdkNoCause));
306 assertSame(cyclicCause.getCause(), ExceptionUtils.getCause(cyclicCause));
307 assertSame(cyclicCause.getCause().getCause(), ExceptionUtils.getCause(cyclicCause.getCause()));
308 assertSame(cyclicCause.getCause(), ExceptionUtils.getCause(cyclicCause.getCause().getCause()));
309 assertSame(withoutCause, ExceptionUtils.getCause(notVisibleException));
310 }
311
312 @SuppressWarnings("deprecation")
313 @Test
314 void testGetCause_ThrowableArray() {
315 assertSame(null, ExceptionUtils.getCause(null, null));
316 assertSame(null, ExceptionUtils.getCause(null, new String[0]));
317
318
319 assertSame(nested, ExceptionUtils.getCause(withCause, null));
320 assertSame(null, ExceptionUtils.getCause(withCause, new String[0]));
321 assertSame(null, ExceptionUtils.getCause(withCause, new String[]{null}));
322 assertSame(nested, ExceptionUtils.getCause(withCause, new String[]{"getCause"}));
323
324
325 assertSame(null, ExceptionUtils.getCause(withoutCause, null));
326 assertSame(null, ExceptionUtils.getCause(withoutCause, new String[0]));
327 assertSame(null, ExceptionUtils.getCause(withoutCause, new String[]{null}));
328 assertSame(null, ExceptionUtils.getCause(withoutCause, new String[]{"getCause"}));
329 assertSame(null, ExceptionUtils.getCause(withoutCause, new String[]{"getTargetException"}));
330 }
331
332 @Test
333 void testGetRootCause_Throwable() {
334 assertSame(null, ExceptionUtils.getRootCause(null));
335 assertSame(withoutCause, ExceptionUtils.getRootCause(withoutCause));
336 assertSame(withoutCause, ExceptionUtils.getRootCause(nested));
337 assertSame(withoutCause, ExceptionUtils.getRootCause(withCause));
338 assertSame(jdkNoCause, ExceptionUtils.getRootCause(jdkNoCause));
339 assertSame(cyclicCause.getCause().getCause(), ExceptionUtils.getRootCause(cyclicCause));
340 }
341
342 @Test
343 void testGetRootCauseStackTrace_Throwable() {
344 assertEquals(0, ExceptionUtils.getRootCauseStackTrace(null).length);
345
346 final Throwable cause = createExceptionWithCause();
347 String[] stackTrace = ExceptionUtils.getRootCauseStackTrace(cause);
348 boolean match = false;
349 for (final String element : stackTrace) {
350 if (element.startsWith(ExceptionUtils.WRAPPED_MARKER)) {
351 match = true;
352 break;
353 }
354 }
355 assertTrue(match);
356
357 stackTrace = ExceptionUtils.getRootCauseStackTrace(withoutCause);
358 match = false;
359 for (final String element : stackTrace) {
360 if (element.startsWith(ExceptionUtils.WRAPPED_MARKER)) {
361 match = true;
362 break;
363 }
364 }
365 assertFalse(match);
366 }
367
368 @Test
369 void testGetRootCauseStackTraceList_Throwable() {
370 assertEquals(0, ExceptionUtils.getRootCauseStackTraceList(null).size());
371
372 final Throwable cause = createExceptionWithCause();
373 List<String> stackTrace = ExceptionUtils.getRootCauseStackTraceList(cause);
374 boolean match = false;
375 for (final String element : stackTrace) {
376 if (element.startsWith(ExceptionUtils.WRAPPED_MARKER)) {
377 match = true;
378 break;
379 }
380 }
381 assertTrue(match);
382
383 stackTrace = ExceptionUtils.getRootCauseStackTraceList(withoutCause);
384 match = false;
385 for (final String element : stackTrace) {
386 if (element.startsWith(ExceptionUtils.WRAPPED_MARKER)) {
387 match = true;
388 break;
389 }
390 }
391 assertFalse(match);
392 }
393
394 @Test
395
396 void testgetStackFramesHappyPath() {
397 final String[] actual = ExceptionUtils.getStackFrames(new Throwable() {
398 private static final long serialVersionUID = 1L;
399
400
401 @Override
402 public void printStackTrace(final PrintWriter s) {
403 s.write("org.apache.commons.lang3.exception.ExceptionUtilsTest$1\n" +
404 "\tat org.apache.commons.lang3.exception.ExceptionUtilsTest.testgetStackFramesGappyPath(ExceptionUtilsTest.java:706)\n" +
405 "\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
406 "\tat com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)\n" +
407 "\tat com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)\n");
408 }
409 });
410
411 assertArrayEquals(new String[]{
412 "org.apache.commons.lang3.exception.ExceptionUtilsTest$1",
413 "\tat org.apache.commons.lang3.exception.ExceptionUtilsTest.testgetStackFramesGappyPath(ExceptionUtilsTest.java:706)",
414 "\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
415 "\tat com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)",
416 "\tat com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)"
417 }, actual);
418 }
419
420 @Test
421
422 void testgetStackFramesNullArg() {
423 final String[] actual = ExceptionUtils.getStackFrames((Throwable) null);
424 assertEquals(0, actual.length);
425 }
426
427 @Test
428 void testGetThrowableCount_Throwable() {
429 assertEquals(0, ExceptionUtils.getThrowableCount(null));
430 assertEquals(1, ExceptionUtils.getThrowableCount(withoutCause));
431 assertEquals(2, ExceptionUtils.getThrowableCount(nested));
432 assertEquals(3, ExceptionUtils.getThrowableCount(withCause));
433 assertEquals(1, ExceptionUtils.getThrowableCount(jdkNoCause));
434 assertEquals(3, ExceptionUtils.getThrowableCount(cyclicCause));
435 }
436
437 @Test
438 void testGetThrowableList_Throwable_jdkNoCause() {
439 final List<?> throwables = ExceptionUtils.getThrowableList(jdkNoCause);
440 assertEquals(1, throwables.size());
441 assertSame(jdkNoCause, throwables.get(0));
442 }
443
444 @Test
445 void testGetThrowableList_Throwable_nested() {
446 final List<?> throwables = ExceptionUtils.getThrowableList(nested);
447 assertEquals(2, throwables.size());
448 assertSame(nested, throwables.get(0));
449 assertSame(withoutCause, throwables.get(1));
450 }
451
452 @Test
453 void testGetThrowableList_Throwable_null() {
454 final List<?> throwables = ExceptionUtils.getThrowableList(null);
455 assertEquals(0, throwables.size());
456 }
457
458 @Test
459 void testGetThrowableList_Throwable_recursiveCause() {
460 final List<?> throwables = ExceptionUtils.getThrowableList(cyclicCause);
461 assertEquals(3, throwables.size());
462 assertSame(cyclicCause, throwables.get(0));
463 assertSame(cyclicCause.getCause(), throwables.get(1));
464 assertSame(cyclicCause.getCause().getCause(), throwables.get(2));
465 }
466
467 @Test
468 void testGetThrowableList_Throwable_withCause() {
469 final List<?> throwables = ExceptionUtils.getThrowableList(withCause);
470 assertEquals(3, throwables.size());
471 assertSame(withCause, throwables.get(0));
472 assertSame(nested, throwables.get(1));
473 assertSame(withoutCause, throwables.get(2));
474 }
475
476 @Test
477 void testGetThrowableList_Throwable_withoutCause() {
478 final List<?> throwables = ExceptionUtils.getThrowableList(withoutCause);
479 assertEquals(1, throwables.size());
480 assertSame(withoutCause, throwables.get(0));
481 }
482
483 @Test
484 void testGetThrowables_Throwable_jdkNoCause() {
485 final Throwable[] throwables = ExceptionUtils.getThrowables(jdkNoCause);
486 assertEquals(1, throwables.length);
487 assertSame(jdkNoCause, throwables[0]);
488 }
489
490 @Test
491 void testGetThrowables_Throwable_nested() {
492 final Throwable[] throwables = ExceptionUtils.getThrowables(nested);
493 assertEquals(2, throwables.length);
494 assertSame(nested, throwables[0]);
495 assertSame(withoutCause, throwables[1]);
496 }
497
498 @Test
499 void testGetThrowables_Throwable_null() {
500 assertEquals(0, ExceptionUtils.getThrowables(null).length);
501 }
502
503 @Test
504 void testGetThrowables_Throwable_recursiveCause() {
505 final Throwable[] throwables = ExceptionUtils.getThrowables(cyclicCause);
506 assertEquals(3, throwables.length);
507 assertSame(cyclicCause, throwables[0]);
508 assertSame(cyclicCause.getCause(), throwables[1]);
509 assertSame(cyclicCause.getCause().getCause(), throwables[2]);
510 }
511
512 @Test
513 void testGetThrowables_Throwable_withCause() {
514 final Throwable[] throwables = ExceptionUtils.getThrowables(withCause);
515 assertEquals(3, throwables.length);
516 assertSame(withCause, throwables[0]);
517 assertSame(nested, throwables[1]);
518 assertSame(withoutCause, throwables[2]);
519 }
520
521 @Test
522 void testGetThrowables_Throwable_withoutCause() {
523 final Throwable[] throwables = ExceptionUtils.getThrowables(withoutCause);
524 assertEquals(1, throwables.length);
525 assertSame(withoutCause, throwables[0]);
526 }
527
528 @Test
529 void testIndexOf_ThrowableClass() {
530 assertEquals(-1, ExceptionUtils.indexOfThrowable(null, null));
531 assertEquals(-1, ExceptionUtils.indexOfThrowable(null, NestableException.class));
532
533 assertEquals(-1, ExceptionUtils.indexOfThrowable(withoutCause, null));
534 assertEquals(-1, ExceptionUtils.indexOfThrowable(withoutCause, ExceptionWithCause.class));
535 assertEquals(-1, ExceptionUtils.indexOfThrowable(withoutCause, NestableException.class));
536 assertEquals(0, ExceptionUtils.indexOfThrowable(withoutCause, ExceptionWithoutCause.class));
537
538 assertEquals(-1, ExceptionUtils.indexOfThrowable(nested, null));
539 assertEquals(-1, ExceptionUtils.indexOfThrowable(nested, ExceptionWithCause.class));
540 assertEquals(0, ExceptionUtils.indexOfThrowable(nested, NestableException.class));
541 assertEquals(1, ExceptionUtils.indexOfThrowable(nested, ExceptionWithoutCause.class));
542
543 assertEquals(-1, ExceptionUtils.indexOfThrowable(withCause, null));
544 assertEquals(0, ExceptionUtils.indexOfThrowable(withCause, ExceptionWithCause.class));
545 assertEquals(1, ExceptionUtils.indexOfThrowable(withCause, NestableException.class));
546 assertEquals(2, ExceptionUtils.indexOfThrowable(withCause, ExceptionWithoutCause.class));
547
548 assertEquals(-1, ExceptionUtils.indexOfThrowable(withCause, Exception.class));
549 assertEquals(-1, ExceptionUtils.indexOfThrowable(withCause, Throwable.class));
550 }
551
552 @Test
553 void testIndexOf_ThrowableClassInt() {
554 assertEquals(-1, ExceptionUtils.indexOfThrowable(null, null, 0));
555 assertEquals(-1, ExceptionUtils.indexOfThrowable(null, NestableException.class, 0));
556
557 assertEquals(-1, ExceptionUtils.indexOfThrowable(withoutCause, null));
558 assertEquals(-1, ExceptionUtils.indexOfThrowable(withoutCause, ExceptionWithCause.class, 0));
559 assertEquals(-1, ExceptionUtils.indexOfThrowable(withoutCause, NestableException.class, 0));
560 assertEquals(0, ExceptionUtils.indexOfThrowable(withoutCause, ExceptionWithoutCause.class, 0));
561
562 assertEquals(-1, ExceptionUtils.indexOfThrowable(nested, null, 0));
563 assertEquals(-1, ExceptionUtils.indexOfThrowable(nested, ExceptionWithCause.class, 0));
564 assertEquals(0, ExceptionUtils.indexOfThrowable(nested, NestableException.class, 0));
565 assertEquals(1, ExceptionUtils.indexOfThrowable(nested, ExceptionWithoutCause.class, 0));
566
567 assertEquals(-1, ExceptionUtils.indexOfThrowable(withCause, null));
568 assertEquals(0, ExceptionUtils.indexOfThrowable(withCause, ExceptionWithCause.class, 0));
569 assertEquals(1, ExceptionUtils.indexOfThrowable(withCause, NestableException.class, 0));
570 assertEquals(2, ExceptionUtils.indexOfThrowable(withCause, ExceptionWithoutCause.class, 0));
571
572 assertEquals(0, ExceptionUtils.indexOfThrowable(withCause, ExceptionWithCause.class, -1));
573 assertEquals(0, ExceptionUtils.indexOfThrowable(withCause, ExceptionWithCause.class, 0));
574 assertEquals(-1, ExceptionUtils.indexOfThrowable(withCause, ExceptionWithCause.class, 1));
575 assertEquals(-1, ExceptionUtils.indexOfThrowable(withCause, ExceptionWithCause.class, 9));
576
577 assertEquals(-1, ExceptionUtils.indexOfThrowable(withCause, Exception.class, 0));
578 assertEquals(-1, ExceptionUtils.indexOfThrowable(withCause, Throwable.class, 0));
579 }
580
581 @Test
582 void testIndexOfType_ThrowableClass() {
583 assertEquals(-1, ExceptionUtils.indexOfType(null, null));
584 assertEquals(-1, ExceptionUtils.indexOfType(null, NestableException.class));
585
586 assertEquals(-1, ExceptionUtils.indexOfType(withoutCause, null));
587 assertEquals(-1, ExceptionUtils.indexOfType(withoutCause, ExceptionWithCause.class));
588 assertEquals(-1, ExceptionUtils.indexOfType(withoutCause, NestableException.class));
589 assertEquals(0, ExceptionUtils.indexOfType(withoutCause, ExceptionWithoutCause.class));
590
591 assertEquals(-1, ExceptionUtils.indexOfType(nested, null));
592 assertEquals(-1, ExceptionUtils.indexOfType(nested, ExceptionWithCause.class));
593 assertEquals(0, ExceptionUtils.indexOfType(nested, NestableException.class));
594 assertEquals(1, ExceptionUtils.indexOfType(nested, ExceptionWithoutCause.class));
595
596 assertEquals(-1, ExceptionUtils.indexOfType(withCause, null));
597 assertEquals(0, ExceptionUtils.indexOfType(withCause, ExceptionWithCause.class));
598 assertEquals(1, ExceptionUtils.indexOfType(withCause, NestableException.class));
599 assertEquals(2, ExceptionUtils.indexOfType(withCause, ExceptionWithoutCause.class));
600
601 assertEquals(0, ExceptionUtils.indexOfType(withCause, Exception.class));
602 assertEquals(0, ExceptionUtils.indexOfType(withCause, Throwable.class));
603 }
604
605 @Test
606 void testIndexOfType_ThrowableClassInt() {
607 assertEquals(-1, ExceptionUtils.indexOfType(null, null, 0));
608 assertEquals(-1, ExceptionUtils.indexOfType(null, NestableException.class, 0));
609
610 assertEquals(-1, ExceptionUtils.indexOfType(withoutCause, null));
611 assertEquals(-1, ExceptionUtils.indexOfType(withoutCause, ExceptionWithCause.class, 0));
612 assertEquals(-1, ExceptionUtils.indexOfType(withoutCause, NestableException.class, 0));
613 assertEquals(0, ExceptionUtils.indexOfType(withoutCause, ExceptionWithoutCause.class, 0));
614
615 assertEquals(-1, ExceptionUtils.indexOfType(nested, null, 0));
616 assertEquals(-1, ExceptionUtils.indexOfType(nested, ExceptionWithCause.class, 0));
617 assertEquals(0, ExceptionUtils.indexOfType(nested, NestableException.class, 0));
618 assertEquals(1, ExceptionUtils.indexOfType(nested, ExceptionWithoutCause.class, 0));
619
620 assertEquals(-1, ExceptionUtils.indexOfType(withCause, null));
621 assertEquals(0, ExceptionUtils.indexOfType(withCause, ExceptionWithCause.class, 0));
622 assertEquals(1, ExceptionUtils.indexOfType(withCause, NestableException.class, 0));
623 assertEquals(2, ExceptionUtils.indexOfType(withCause, ExceptionWithoutCause.class, 0));
624
625 assertEquals(0, ExceptionUtils.indexOfType(withCause, ExceptionWithCause.class, -1));
626 assertEquals(0, ExceptionUtils.indexOfType(withCause, ExceptionWithCause.class, 0));
627 assertEquals(-1, ExceptionUtils.indexOfType(withCause, ExceptionWithCause.class, 1));
628 assertEquals(-1, ExceptionUtils.indexOfType(withCause, ExceptionWithCause.class, 9));
629
630 assertEquals(0, ExceptionUtils.indexOfType(withCause, Exception.class, 0));
631 assertEquals(0, ExceptionUtils.indexOfType(withCause, Throwable.class, 0));
632 }
633
634 @Test
635 void testIsChecked_checked() {
636 assertTrue(ExceptionUtils.isChecked(new IOException()));
637 }
638
639 @Test
640 void testIsChecked_error() {
641 assertFalse(ExceptionUtils.isChecked(new StackOverflowError()));
642 }
643
644 @Test
645 void testIsChecked_null() {
646 assertFalse(ExceptionUtils.isChecked(null));
647 }
648
649 @Test
650 void testIsChecked_unchecked() {
651 assertFalse(ExceptionUtils.isChecked(new IllegalArgumentException()));
652 }
653
654 @Test
655 void testIsCheckedCustomThrowable() {
656 assertTrue(ExceptionUtils.isChecked(new TestThrowable()));
657 }
658
659 @Test
660 void testIsUnchecked_checked() {
661 assertFalse(ExceptionUtils.isUnchecked(new IOException()));
662 }
663
664 @Test
665 void testIsUnchecked_error() {
666 assertTrue(ExceptionUtils.isUnchecked(new StackOverflowError()));
667 }
668
669 @Test
670 void testIsUnchecked_null() {
671 assertFalse(ExceptionUtils.isUnchecked(null));
672 }
673
674 @Test
675 void testIsUnchecked_unchecked() {
676 assertTrue(ExceptionUtils.isUnchecked(new IllegalArgumentException()));
677 }
678
679 @Test
680 void testIsUnCheckedCustomThrowable() {
681 assertFalse(ExceptionUtils.isUnchecked(new TestThrowable()));
682 }
683
684 @Test
685 void testPrintRootCauseStackTrace_Throwable() {
686 ExceptionUtils.printRootCauseStackTrace(null);
687
688
689 }
690
691 @Test
692 void testPrintRootCauseStackTrace_ThrowableStream() {
693 ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
694 ExceptionUtils.printRootCauseStackTrace(null, (PrintStream) null);
695 ExceptionUtils.printRootCauseStackTrace(null, new PrintStream(out));
696 assertEquals(0, out.toString().length());
697 assertNullPointerException(() -> ExceptionUtils.printRootCauseStackTrace(withCause, (PrintStream) null));
698 out = new ByteArrayOutputStream(1024);
699 final Throwable cause = createExceptionWithCause();
700 ExceptionUtils.printRootCauseStackTrace(cause, new PrintStream(out));
701 String stackTrace = out.toString();
702 assertTrue(stackTrace.contains(ExceptionUtils.WRAPPED_MARKER));
703 out = new ByteArrayOutputStream(1024);
704 ExceptionUtils.printRootCauseStackTrace(withoutCause, new PrintStream(out));
705 stackTrace = out.toString();
706 assertFalse(stackTrace.contains(ExceptionUtils.WRAPPED_MARKER));
707 }
708
709 @Test
710 void testPrintRootCauseStackTrace_ThrowableWriter() {
711 StringWriter writer = new StringWriter(1024);
712 ExceptionUtils.printRootCauseStackTrace(null, (PrintWriter) null);
713 ExceptionUtils.printRootCauseStackTrace(null, new PrintWriter(writer));
714 assertEquals(0, writer.getBuffer().length());
715 assertNullPointerException(() -> ExceptionUtils.printRootCauseStackTrace(withCause, (PrintWriter) null));
716 writer = new StringWriter(1024);
717 final Throwable cause = createExceptionWithCause();
718 ExceptionUtils.printRootCauseStackTrace(cause, new PrintWriter(writer));
719 String stackTrace = writer.toString();
720 assertTrue(stackTrace.contains(ExceptionUtils.WRAPPED_MARKER));
721 writer = new StringWriter(1024);
722 ExceptionUtils.printRootCauseStackTrace(withoutCause, new PrintWriter(writer));
723 stackTrace = writer.toString();
724 assertFalse(stackTrace.contains(ExceptionUtils.WRAPPED_MARKER));
725 }
726
727 @Test
728 void testRemoveCommonFrames_ListList() {
729 assertNullPointerException(() -> ExceptionUtils.removeCommonFrames(null, null));
730 }
731
732 @Test
733 void testRethrow() {
734 final Exception expected = new InterruptedException();
735
736 assertThrows(expected.getClass(), () -> {
737 @SuppressWarnings("unused")
738 final Object retVal = ExceptionUtils.rethrow(expected);
739 });
740
741 assertThrows(expected.getClass(), () -> {
742 @SuppressWarnings("unused")
743 final String retVal = ExceptionUtils.rethrow(expected);
744 });
745
746 assertThrows(expected.getClass(), () -> {
747 @SuppressWarnings("unused")
748 final int retVal = ExceptionUtils.rethrow(expected);
749 });
750
751 assertSame(expected, assertThrows(expected.getClass(), () -> ExceptionUtils.rethrow(expected)));
752 assertNotSame(expected, assertThrows(expected.getClass(), () -> ExceptionUtils.rethrow(new InterruptedException())));
753 }
754
755 @Test
756 void testStream_jdkNoCause() {
757 assertEquals(1, ExceptionUtils.stream(jdkNoCause).count());
758 assertSame(jdkNoCause, ExceptionUtils.stream(jdkNoCause).toArray()[0]);
759 }
760
761 @Test
762 void testStream_nested() {
763 assertEquals(2, ExceptionUtils.stream(nested).count());
764 final Object[] array = ExceptionUtils.stream(nested).toArray();
765 assertSame(nested, array[0]);
766 assertSame(withoutCause, array[1]);
767 }
768
769 @Test
770 void testStream_null() {
771 assertEquals(0, ExceptionUtils.stream(null).count());
772 }
773
774 @Test
775 void testStream_recursiveCause() {
776 final List<?> throwables = ExceptionUtils.stream(cyclicCause).collect(Collectors.toList());
777 assertEquals(3, throwables.size());
778 assertSame(cyclicCause, throwables.get(0));
779 assertSame(cyclicCause.getCause(), throwables.get(1));
780 assertSame(cyclicCause.getCause().getCause(), throwables.get(2));
781 }
782
783 @Test
784 void testStream_withCause() {
785 final List<?> throwables = ExceptionUtils.stream(withCause).collect(Collectors.toList());
786 assertEquals(3, throwables.size());
787 assertSame(withCause, throwables.get(0));
788 assertSame(nested, throwables.get(1));
789 assertSame(withoutCause, throwables.get(2));
790 }
791
792 @Test
793 void testStream_withoutCause() {
794 final List<?> throwables = ExceptionUtils.stream(withoutCause).collect(Collectors.toList());
795 assertEquals(1, throwables.size());
796 assertSame(withoutCause, throwables.get(0));
797 }
798
799 @Test
800 void testThrowableOf_ThrowableClass() {
801 assertNull(ExceptionUtils.throwableOfThrowable(null, null));
802 assertNull(ExceptionUtils.throwableOfThrowable(null, NestableException.class));
803
804 assertNull(ExceptionUtils.throwableOfThrowable(withoutCause, null));
805 assertNull(ExceptionUtils.throwableOfThrowable(withoutCause, ExceptionWithCause.class));
806 assertNull(ExceptionUtils.throwableOfThrowable(withoutCause, NestableException.class));
807 assertEquals(withoutCause, ExceptionUtils.throwableOfThrowable(withoutCause, ExceptionWithoutCause.class));
808
809 assertNull(ExceptionUtils.throwableOfThrowable(nested, null));
810 assertNull(ExceptionUtils.throwableOfThrowable(nested, ExceptionWithCause.class));
811 assertEquals(nested, ExceptionUtils.throwableOfThrowable(nested, NestableException.class));
812 assertEquals(nested.getCause(), ExceptionUtils.throwableOfThrowable(nested, ExceptionWithoutCause.class));
813
814 assertNull(ExceptionUtils.throwableOfThrowable(withCause, null));
815 assertEquals(withCause, ExceptionUtils.throwableOfThrowable(withCause, ExceptionWithCause.class));
816 assertEquals(withCause.getCause(), ExceptionUtils.throwableOfThrowable(withCause, NestableException.class));
817 assertEquals(withCause.getCause().getCause(), ExceptionUtils.throwableOfThrowable(withCause, ExceptionWithoutCause.class));
818
819 assertNull(ExceptionUtils.throwableOfThrowable(withCause, Exception.class));
820 assertNull(ExceptionUtils.throwableOfThrowable(withCause, Throwable.class));
821 }
822
823 @Test
824 void testThrowableOf_ThrowableClassInt() {
825 assertNull(ExceptionUtils.throwableOfThrowable(null, null, 0));
826 assertNull(ExceptionUtils.throwableOfThrowable(null, NestableException.class, 0));
827
828 assertNull(ExceptionUtils.throwableOfThrowable(withoutCause, null));
829 assertNull(ExceptionUtils.throwableOfThrowable(withoutCause, ExceptionWithCause.class, 0));
830 assertNull(ExceptionUtils.throwableOfThrowable(withoutCause, NestableException.class, 0));
831 assertEquals(withoutCause, ExceptionUtils.throwableOfThrowable(withoutCause, ExceptionWithoutCause.class, 0));
832
833 assertNull(ExceptionUtils.throwableOfThrowable(nested, null, 0));
834 assertNull(ExceptionUtils.throwableOfThrowable(nested, ExceptionWithCause.class, 0));
835 assertEquals(nested, ExceptionUtils.throwableOfThrowable(nested, NestableException.class, 0));
836 assertEquals(nested.getCause(), ExceptionUtils.throwableOfThrowable(nested, ExceptionWithoutCause.class, 0));
837
838 assertNull(ExceptionUtils.throwableOfThrowable(withCause, null));
839 assertEquals(withCause, ExceptionUtils.throwableOfThrowable(withCause, ExceptionWithCause.class, 0));
840 assertEquals(withCause.getCause(), ExceptionUtils.throwableOfThrowable(withCause, NestableException.class, 0));
841 assertEquals(withCause.getCause().getCause(), ExceptionUtils.throwableOfThrowable(withCause, ExceptionWithoutCause.class, 0));
842
843 assertEquals(withCause, ExceptionUtils.throwableOfThrowable(withCause, ExceptionWithCause.class, -1));
844 assertEquals(withCause, ExceptionUtils.throwableOfThrowable(withCause, ExceptionWithCause.class, 0));
845 assertNull(ExceptionUtils.throwableOfThrowable(withCause, ExceptionWithCause.class, 1));
846 assertNull(ExceptionUtils.throwableOfThrowable(withCause, ExceptionWithCause.class, 9));
847
848 assertNull(ExceptionUtils.throwableOfThrowable(withCause, Exception.class, 0));
849 assertNull(ExceptionUtils.throwableOfThrowable(withCause, Throwable.class, 0));
850 }
851
852 @Test
853 void testThrowableOfType_ThrowableClass() {
854 assertNull(ExceptionUtils.throwableOfType(null, null));
855 assertNull(ExceptionUtils.throwableOfType(null, NestableException.class));
856
857 assertNull(ExceptionUtils.throwableOfType(withoutCause, null));
858 assertNull(ExceptionUtils.throwableOfType(withoutCause, ExceptionWithCause.class));
859 assertNull(ExceptionUtils.throwableOfType(withoutCause, NestableException.class));
860 assertEquals(withoutCause, ExceptionUtils.throwableOfType(withoutCause, ExceptionWithoutCause.class));
861
862 assertNull(ExceptionUtils.throwableOfType(nested, null));
863 assertNull(ExceptionUtils.throwableOfType(nested, ExceptionWithCause.class));
864 assertEquals(nested, ExceptionUtils.throwableOfType(nested, NestableException.class));
865 assertEquals(nested.getCause(), ExceptionUtils.throwableOfType(nested, ExceptionWithoutCause.class));
866
867 assertNull(ExceptionUtils.throwableOfType(withCause, null));
868 assertEquals(withCause, ExceptionUtils.throwableOfType(withCause, ExceptionWithCause.class));
869 assertEquals(withCause.getCause(), ExceptionUtils.throwableOfType(withCause, NestableException.class));
870 assertEquals(withCause.getCause().getCause(), ExceptionUtils.throwableOfType(withCause, ExceptionWithoutCause.class));
871
872 assertEquals(withCause, ExceptionUtils.throwableOfType(withCause, Exception.class));
873 assertEquals(withCause, ExceptionUtils.throwableOfType(withCause, Throwable.class));
874 }
875
876 @Test
877 void testThrowableOfType_ThrowableClassInt() {
878 assertNull(ExceptionUtils.throwableOfType(null, null, 0));
879 assertNull(ExceptionUtils.throwableOfType(null, NestableException.class, 0));
880
881 assertNull(ExceptionUtils.throwableOfType(withoutCause, null));
882 assertNull(ExceptionUtils.throwableOfType(withoutCause, ExceptionWithCause.class, 0));
883 assertNull(ExceptionUtils.throwableOfType(withoutCause, NestableException.class, 0));
884 assertEquals(withoutCause, ExceptionUtils.throwableOfType(withoutCause, ExceptionWithoutCause.class, 0));
885
886 assertNull(ExceptionUtils.throwableOfType(nested, null, 0));
887 assertNull(ExceptionUtils.throwableOfType(nested, ExceptionWithCause.class, 0));
888 assertEquals(nested, ExceptionUtils.throwableOfType(nested, NestableException.class, 0));
889 assertEquals(nested.getCause(), ExceptionUtils.throwableOfType(nested, ExceptionWithoutCause.class, 0));
890
891 assertNull(ExceptionUtils.throwableOfType(withCause, null));
892 assertEquals(withCause, ExceptionUtils.throwableOfType(withCause, ExceptionWithCause.class, 0));
893 assertEquals(withCause.getCause(), ExceptionUtils.throwableOfType(withCause, NestableException.class, 0));
894 assertEquals(withCause.getCause().getCause(), ExceptionUtils.throwableOfType(withCause, ExceptionWithoutCause.class, 0));
895
896 assertEquals(withCause, ExceptionUtils.throwableOfType(withCause, ExceptionWithCause.class, -1));
897 assertEquals(withCause, ExceptionUtils.throwableOfType(withCause, ExceptionWithCause.class, 0));
898 assertNull(ExceptionUtils.throwableOfType(withCause, ExceptionWithCause.class, 1));
899 assertNull(ExceptionUtils.throwableOfType(withCause, ExceptionWithCause.class, 9));
900
901 assertEquals(withCause, ExceptionUtils.throwableOfType(withCause, Exception.class, 0));
902 assertEquals(withCause, ExceptionUtils.throwableOfType(withCause, Throwable.class, 0));
903 }
904
905 @Test
906 void testWrapAndUnwrapCheckedException() {
907 final Throwable t = assertThrows(Throwable.class, () -> ExceptionUtils.wrapAndThrow(new IOException()));
908 assertTrue(ExceptionUtils.hasCause(t, IOException.class));
909 }
910
911 @Test
912 void testWrapAndUnwrapError() {
913 final Throwable t = assertThrows(Throwable.class, () -> ExceptionUtils.wrapAndThrow(new OutOfMemoryError()));
914 assertTrue(ExceptionUtils.hasCause(t, Error.class));
915 }
916
917 @Test
918 void testWrapAndUnwrapRuntimeException() {
919 final Throwable t = assertThrows(Throwable.class, () -> ExceptionUtils.wrapAndThrow(new IllegalArgumentException()));
920 assertTrue(ExceptionUtils.hasCause(t, RuntimeException.class));
921 }
922
923 @Test
924 void testWrapAndUnwrapThrowable() {
925 final Throwable t = assertThrows(Throwable.class, () -> ExceptionUtils.wrapAndThrow(new TestThrowable()));
926 assertTrue(ExceptionUtils.hasCause(t, TestThrowable.class));
927 }
928 }