• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.base;
18 
19 import static com.google.common.base.Throwables.getStackTraceAsString;
20 import static java.util.Arrays.asList;
21 import static java.util.regex.Pattern.quote;
22 
23 import com.google.common.collect.Iterables;
24 import com.google.common.testing.NullPointerTester;
25 
26 import junit.framework.TestCase;
27 
28 import java.io.FileNotFoundException;
29 import java.util.List;
30 
31 /**
32  * Unit test for {@link Throwables}.
33  *
34  * @author Kevin Bourrillion
35  */
36 public class ThrowablesTest extends TestCase {
testPropagateIfPossible_NoneDeclared_NoneThrown()37   public void testPropagateIfPossible_NoneDeclared_NoneThrown() {
38     Sample sample = new Sample() {
39       @Override public void noneDeclared() {
40         try {
41           methodThatDoesntThrowAnything();
42         } catch (Throwable t) {
43           Throwables.propagateIfPossible(t);
44           throw new SomeChainingException(t);
45         }
46       }
47     };
48 
49     // Expect no exception to be thrown
50     sample.noneDeclared();
51   }
52 
testPropagateIfPossible_NoneDeclared_UncheckedThrown()53   public void testPropagateIfPossible_NoneDeclared_UncheckedThrown() {
54     Sample sample = new Sample() {
55       @Override public void noneDeclared() {
56         try {
57           methodThatThrowsUnchecked();
58         } catch (Throwable t) {
59           Throwables.propagateIfPossible(t);
60           throw new SomeChainingException(t);
61         }
62       }
63     };
64 
65     // Expect the unchecked exception to propagate as-is
66     try {
67       sample.noneDeclared();
68       fail();
69     } catch (SomeUncheckedException expected) {
70     }
71   }
72 
testPropagateIfPossible_NoneDeclared_UndeclaredThrown()73   public void testPropagateIfPossible_NoneDeclared_UndeclaredThrown() {
74     Sample sample = new Sample() {
75       @Override public void noneDeclared() {
76         try {
77           methodThatThrowsUndeclaredChecked();
78         } catch (Throwable t) {
79           Throwables.propagateIfPossible(t);
80           throw new SomeChainingException(t);
81         }
82       }
83     };
84 
85     // Expect the undeclared exception to have been chained inside another
86     try {
87       sample.noneDeclared();
88       fail();
89     } catch (SomeChainingException expected) {
90     }
91   }
92 
testPropagateIfPossible_OneDeclared_NoneThrown()93   public void testPropagateIfPossible_OneDeclared_NoneThrown()
94       throws SomeCheckedException {
95     Sample sample = new Sample() {
96       @Override public void oneDeclared() throws SomeCheckedException {
97         try {
98           methodThatDoesntThrowAnything();
99         } catch (Throwable t) {
100           // yes, this block is never reached, but for purposes of illustration
101           // we're keeping it the same in each test
102           Throwables.propagateIfPossible(t, SomeCheckedException.class);
103           throw new SomeChainingException(t);
104         }
105       }
106     };
107 
108     // Expect no exception to be thrown
109     sample.oneDeclared();
110   }
111 
testPropagateIfPossible_OneDeclared_UncheckedThrown()112   public void testPropagateIfPossible_OneDeclared_UncheckedThrown()
113       throws SomeCheckedException {
114     Sample sample = new Sample() {
115       @Override public void oneDeclared() throws SomeCheckedException {
116         try {
117           methodThatThrowsUnchecked();
118         } catch (Throwable t) {
119           Throwables.propagateIfPossible(t, SomeCheckedException.class);
120           throw new SomeChainingException(t);
121         }
122       }
123     };
124 
125     // Expect the unchecked exception to propagate as-is
126     try {
127       sample.oneDeclared();
128       fail();
129     } catch (SomeUncheckedException expected) {
130     }
131   }
132 
testPropagateIfPossible_OneDeclared_CheckedThrown()133   public void testPropagateIfPossible_OneDeclared_CheckedThrown() {
134     Sample sample = new Sample() {
135       @Override public void oneDeclared() throws SomeCheckedException {
136         try {
137           methodThatThrowsChecked();
138         } catch (Throwable t) {
139           Throwables.propagateIfPossible(t, SomeCheckedException.class);
140           throw new SomeChainingException(t);
141         }
142       }
143     };
144 
145     // Expect the checked exception to propagate as-is
146     try {
147       sample.oneDeclared();
148       fail();
149     } catch (SomeCheckedException expected) {
150     }
151   }
152 
testPropagateIfPossible_OneDeclared_UndeclaredThrown()153   public void testPropagateIfPossible_OneDeclared_UndeclaredThrown()
154       throws SomeCheckedException {
155     Sample sample = new Sample() {
156       @Override public void oneDeclared() throws SomeCheckedException {
157         try {
158           methodThatThrowsUndeclaredChecked();
159         } catch (Throwable t) {
160           Throwables.propagateIfPossible(t, SomeCheckedException.class);
161           throw new SomeChainingException(t);
162         }
163       }
164     };
165 
166     // Expect the undeclared exception to have been chained inside another
167     try {
168       sample.oneDeclared();
169       fail();
170     } catch (SomeChainingException expected) {
171     }
172   }
173 
testPropagateIfPossible_TwoDeclared_NoneThrown()174   public void testPropagateIfPossible_TwoDeclared_NoneThrown()
175       throws SomeCheckedException, SomeOtherCheckedException {
176     Sample sample = new Sample() {
177       @Override public void twoDeclared() throws SomeCheckedException,
178           SomeOtherCheckedException {
179         try {
180           methodThatDoesntThrowAnything();
181         } catch (Throwable t) {
182           Throwables.propagateIfPossible(t, SomeCheckedException.class,
183               SomeOtherCheckedException.class);
184           throw new SomeChainingException(t);
185         }
186       }
187     };
188 
189     // Expect no exception to be thrown
190     sample.twoDeclared();
191   }
192 
testPropagateIfPossible_TwoDeclared_UncheckedThrown()193   public void testPropagateIfPossible_TwoDeclared_UncheckedThrown()
194       throws SomeCheckedException, SomeOtherCheckedException {
195     Sample sample = new Sample() {
196       @Override public void twoDeclared() throws SomeCheckedException,
197           SomeOtherCheckedException {
198         try {
199           methodThatThrowsUnchecked();
200         } catch (Throwable t) {
201           Throwables.propagateIfPossible(t, SomeCheckedException.class,
202               SomeOtherCheckedException.class);
203           throw new SomeChainingException(t);
204         }
205       }
206     };
207 
208     // Expect the unchecked exception to propagate as-is
209     try {
210       sample.twoDeclared();
211       fail();
212     } catch (SomeUncheckedException expected) {
213     }
214   }
215 
testPropagateIfPossible_TwoDeclared_CheckedThrown()216   public void testPropagateIfPossible_TwoDeclared_CheckedThrown()
217       throws SomeOtherCheckedException {
218     Sample sample = new Sample() {
219       @Override public void twoDeclared() throws SomeCheckedException,
220           SomeOtherCheckedException {
221         try {
222           methodThatThrowsChecked();
223         } catch (Throwable t) {
224           Throwables.propagateIfPossible(t, SomeCheckedException.class,
225               SomeOtherCheckedException.class);
226           throw new SomeChainingException(t);
227         }
228       }
229     };
230 
231     // Expect the checked exception to propagate as-is
232     try {
233       sample.twoDeclared();
234       fail();
235     } catch (SomeCheckedException expected) {
236     }
237   }
238 
testPropagateIfPossible_TwoDeclared_OtherCheckedThrown()239   public void testPropagateIfPossible_TwoDeclared_OtherCheckedThrown()
240       throws SomeCheckedException {
241     Sample sample = new Sample() {
242       @Override public void twoDeclared() throws SomeCheckedException,
243           SomeOtherCheckedException {
244         try {
245           methodThatThrowsOtherChecked();
246         } catch (Throwable t) {
247           Throwables.propagateIfPossible(t, SomeCheckedException.class,
248               SomeOtherCheckedException.class);
249           throw new SomeChainingException(t);
250         }
251       }
252     };
253 
254     // Expect the checked exception to propagate as-is
255     try {
256       sample.twoDeclared();
257       fail();
258     } catch (SomeOtherCheckedException expected) {
259     }
260   }
261 
testPropageIfPossible_null()262   public void testPropageIfPossible_null() throws SomeCheckedException {
263     Throwables.propagateIfPossible(null);
264     Throwables.propagateIfPossible(null, SomeCheckedException.class);
265     Throwables.propagateIfPossible(null, SomeCheckedException.class,
266         SomeUncheckedException.class);
267   }
268 
testPropagate_NoneDeclared_NoneThrown()269   public void testPropagate_NoneDeclared_NoneThrown() {
270     Sample sample = new Sample() {
271       @Override public void noneDeclared() {
272         try {
273           methodThatDoesntThrowAnything();
274         } catch (Throwable t) {
275           throw Throwables.propagate(t);
276         }
277       }
278     };
279 
280     // Expect no exception to be thrown
281     sample.noneDeclared();
282   }
283 
testPropagate_NoneDeclared_UncheckedThrown()284   public void testPropagate_NoneDeclared_UncheckedThrown() {
285     Sample sample = new Sample() {
286       @Override public void noneDeclared() {
287         try {
288           methodThatThrowsUnchecked();
289         } catch (Throwable t) {
290           throw Throwables.propagate(t);
291         }
292       }
293     };
294 
295     // Expect the unchecked exception to propagate as-is
296     try {
297       sample.noneDeclared();
298       fail();
299     } catch (SomeUncheckedException expected) {
300     }
301   }
302 
testPropagate_NoneDeclared_ErrorThrown()303   public void testPropagate_NoneDeclared_ErrorThrown() {
304     Sample sample = new Sample() {
305       @Override public void noneDeclared() {
306         try {
307           methodThatThrowsError();
308         } catch (Throwable t) {
309           throw Throwables.propagate(t);
310         }
311       }
312     };
313 
314     // Expect the error to propagate as-is
315     try {
316       sample.noneDeclared();
317       fail();
318     } catch (SomeError expected) {
319     }
320   }
321 
testPropagate_NoneDeclared_CheckedThrown()322   public void testPropagate_NoneDeclared_CheckedThrown() {
323     Sample sample = new Sample() {
324       @Override public void noneDeclared() {
325         try {
326           methodThatThrowsChecked();
327         } catch (Throwable t) {
328           throw Throwables.propagate(t);
329         }
330       }
331     };
332 
333     // Expect the undeclared exception to have been chained inside another
334     try {
335       sample.noneDeclared();
336       fail();
337     } catch (RuntimeException expected) {
338       assertTrue(expected.getCause() instanceof SomeCheckedException);
339     }
340   }
341 
testPropagateIfInstanceOf_NoneThrown()342   public void testPropagateIfInstanceOf_NoneThrown()
343       throws SomeCheckedException {
344     Sample sample = new Sample() {
345       @Override public void oneDeclared() throws SomeCheckedException {
346         try {
347           methodThatDoesntThrowAnything();
348         } catch (Throwable t) {
349           Throwables.propagateIfInstanceOf(t, SomeCheckedException.class);
350           throw Throwables.propagate(t);
351         }
352       }
353     };
354 
355     // Expect no exception to be thrown
356     sample.oneDeclared();
357   }
358 
testPropagateIfInstanceOf_DeclaredThrown()359   public void testPropagateIfInstanceOf_DeclaredThrown() {
360     Sample sample = new Sample() {
361       @Override public void oneDeclared() throws SomeCheckedException {
362         try {
363           methodThatThrowsChecked();
364         } catch (Throwable t) {
365           Throwables.propagateIfInstanceOf(t, SomeCheckedException.class);
366           throw Throwables.propagate(t);
367         }
368       }
369     };
370 
371     // Expect declared exception to be thrown as-is
372     try {
373       sample.oneDeclared();
374       fail();
375     } catch (SomeCheckedException e) {
376     }
377   }
378 
testPropagateIfInstanceOf_UncheckedThrown()379   public void testPropagateIfInstanceOf_UncheckedThrown()
380       throws SomeCheckedException {
381     Sample sample = new Sample() {
382       @Override public void oneDeclared() throws SomeCheckedException {
383         try {
384           methodThatThrowsUnchecked();
385         } catch (Throwable t) {
386           Throwables.propagateIfInstanceOf(t, SomeCheckedException.class);
387           throw Throwables.propagate(t);
388         }
389       }
390     };
391 
392     // Expect unchecked exception to be thrown as-is
393     try {
394       sample.oneDeclared();
395       fail();
396     } catch (SomeUncheckedException e) {
397     }
398   }
399 
testPropagateIfInstanceOf_UndeclaredThrown()400   public void testPropagateIfInstanceOf_UndeclaredThrown()
401       throws SomeCheckedException {
402     Sample sample = new Sample() {
403       @Override public void oneDeclared() throws SomeCheckedException {
404         try {
405           methodThatThrowsOtherChecked();
406         } catch (Throwable t) {
407           Throwables.propagateIfInstanceOf(t, SomeCheckedException.class);
408           throw Throwables.propagate(t);
409         }
410       }
411     };
412 
413     // Expect undeclared exception wrapped by RuntimeException to be thrown
414     try {
415       sample.oneDeclared();
416       fail();
417     } catch (RuntimeException e) {
418       assertTrue(e.getCause() instanceof SomeOtherCheckedException);
419     }
420   }
421 
testPropageIfInstanceOf_null()422   public void testPropageIfInstanceOf_null() throws SomeCheckedException {
423     Throwables.propagateIfInstanceOf(null, SomeCheckedException.class);
424   }
425 
testGetRootCause_NoCause()426   public void testGetRootCause_NoCause() {
427     SomeCheckedException exception = new SomeCheckedException();
428     assertSame(exception, Throwables.getRootCause(exception));
429   }
430 
testGetRootCause_SingleWrapped()431   public void testGetRootCause_SingleWrapped() {
432     SomeCheckedException cause = new SomeCheckedException();
433     SomeChainingException exception = new SomeChainingException(cause);
434     assertSame(cause, Throwables.getRootCause(exception));
435   }
436 
testGetRootCause_DoubleWrapped()437   public void testGetRootCause_DoubleWrapped() {
438     SomeCheckedException cause = new SomeCheckedException();
439     SomeChainingException exception =
440         new SomeChainingException(new SomeChainingException(cause));
441     assertSame(cause, Throwables.getRootCause(exception));
442   }
443 
444   private static class SomeError extends Error {}
445   private static class SomeCheckedException extends Exception {}
446   private static class SomeOtherCheckedException extends Exception {}
447   private static class SomeUncheckedException extends RuntimeException {}
448   private static class SomeUndeclaredCheckedException extends Exception {}
449   private static class SomeChainingException extends RuntimeException {
SomeChainingException(Throwable cause)450     public SomeChainingException(Throwable cause) {
451       super(cause);
452     }
453   }
454 
455   static class Sample {
noneDeclared()456     void noneDeclared() {}
oneDeclared()457     void oneDeclared() throws SomeCheckedException {}
twoDeclared()458     void twoDeclared() throws SomeCheckedException, SomeOtherCheckedException {}
459   }
460 
methodThatDoesntThrowAnything()461   static void methodThatDoesntThrowAnything() {}
methodThatThrowsError()462   static void methodThatThrowsError() {
463     throw new SomeError();
464   }
methodThatThrowsUnchecked()465   static void methodThatThrowsUnchecked() {
466     throw new SomeUncheckedException();
467   }
methodThatThrowsChecked()468   static void methodThatThrowsChecked() throws SomeCheckedException {
469     throw new SomeCheckedException();
470   }
methodThatThrowsOtherChecked()471   static void methodThatThrowsOtherChecked() throws SomeOtherCheckedException {
472     throw new SomeOtherCheckedException();
473   }
methodThatThrowsUndeclaredChecked()474   static void methodThatThrowsUndeclaredChecked()
475       throws SomeUndeclaredCheckedException {
476     throw new SomeUndeclaredCheckedException();
477   }
478 
testGetStackTraceAsString()479   public void testGetStackTraceAsString() {
480     class StackTraceException extends Exception {
481       StackTraceException(String message) {
482         super(message);
483       }
484     }
485 
486     StackTraceException e = new StackTraceException("my message");
487 
488     String firstLine = quote(e.getClass().getName() + ": " + e.getMessage());
489     String secondLine = "\\s*at " + ThrowablesTest.class.getName() + "\\..*";
490     String moreLines = "(?:.*\n?)*";
491     String expected = firstLine + "\n" + secondLine + "\n" + moreLines;
492     assertTrue(getStackTraceAsString(e).matches(expected));
493   }
494 
testGetCausalChain()495   public void testGetCausalChain() {
496     FileNotFoundException fnfe = new FileNotFoundException();
497     IllegalArgumentException iae = new IllegalArgumentException(fnfe);
498     RuntimeException re = new RuntimeException(iae);
499     IllegalStateException ex = new IllegalStateException(re);
500 
501     assertEquals(asList(ex, re, iae, fnfe), Throwables.getCausalChain(ex));
502     assertSame(fnfe, Iterables.getOnlyElement(Throwables.getCausalChain(fnfe)));
503     try {
504       Throwables.getCausalChain(null);
505       fail("Should have throw NPE");
506     } catch (NullPointerException expected) {
507     }
508 
509     List<Throwable> causes = Throwables.getCausalChain(ex);
510     try {
511       causes.add(new RuntimeException());
512       fail("List should be unmodifiable");
513     } catch (UnsupportedOperationException expected) {
514     }
515   }
516 
testNullPointers()517   public void testNullPointers() {
518     new NullPointerTester().testAllPublicStaticMethods(Throwables.class);
519   }
520 }
521