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