/** * Stores the given throwable and rethrows it. It will be rethrown as is if it is an * {@code IOException}, {@code RuntimeException}, {@code Error} or a checked exception of the * given type. Otherwise, it will be rethrown wrapped in a {@code RuntimeException}. <b>Note:</b> * Be sure to declare all of the checked exception types your try block can throw when calling an * overload of this method so as to avoid losing the original exception type. * * <p>This method always throws, and as such should be called as * {@code throw closer.rethrow(e, ...);} to ensure the compiler knows that it will throw. * * @return this method does not return; it always throws * @throws IOException when the given throwable is an IOException * @throws X when the given throwable is of the declared type X */ public <X extends Exception> RuntimeException rethrow(Throwable e, Class<X> declaredType) throws IOException, X { checkNotNull(e); thrown = e; Throwables.propagateIfPossible(e, IOException.class); Throwables.propagateIfPossible(e, declaredType); throw new RuntimeException(e); }
/** * Stores the given throwable and rethrows it. It will be rethrown as is if it is an * {@code IOException}, {@code RuntimeException}, {@code Error} or a checked exception of either * of the given types. Otherwise, it will be rethrown wrapped in a {@code RuntimeException}. * <b>Note:</b> Be sure to declare all of the checked exception types your try block can throw * when calling an overload of this method so as to avoid losing the original exception type. * * <p>This method always throws, and as such should be called as * {@code throw closer.rethrow(e, ...);} to ensure the compiler knows that it will throw. * * @return this method does not return; it always throws * @throws IOException when the given throwable is an IOException * @throws X1 when the given throwable is of the declared type X1 * @throws X2 when the given throwable is of the declared type X2 */ public <X1 extends Exception, X2 extends Exception> RuntimeException rethrow( Throwable e, Class<X1> declaredType1, Class<X2> declaredType2) throws IOException, X1, X2 { checkNotNull(e); thrown = e; Throwables.propagateIfPossible(e, IOException.class); Throwables.propagateIfPossible(e, declaredType1, declaredType2); throw new RuntimeException(e); }
/** * Stores the given throwable and rethrows it. It will be rethrown as is if it is an * {@code IOException}, {@code RuntimeException} or {@code Error}. Otherwise, it will be rethrown * wrapped in a {@code RuntimeException}. <b>Note:</b> Be sure to declare all of the checked * exception types your try block can throw when calling an overload of this method so as to avoid * losing the original exception type. * * <p>This method always throws, and as such should be called as * {@code throw closer.rethrow(e);} to ensure the compiler knows that it will throw. * * @return this method does not return; it always throws * @throws IOException when the given throwable is an IOException */ public RuntimeException rethrow(Throwable e) throws IOException { checkNotNull(e); thrown = e; Throwables.propagateIfPossible(e, IOException.class); throw new RuntimeException(e); }
/** * Propagates {@code throwable} exactly as-is, if and only if it is an instance of {@link * RuntimeException}, {@link Error}, or {@code declaredType}. Example usage: * <pre> * try { * someMethodThatCouldThrowAnything(); * } catch (IKnowWhatToDoWithThisException e) { * handle(e); * } catch (Throwable t) { * Throwables.propagateIfPossible(t, OtherException.class); * throw new RuntimeException("unexpected", t); * } * </pre> * * @param throwable the Throwable to possibly propagate * @param declaredType the single checked exception type declared by the calling method */ public static <X extends Throwable> void propagateIfPossible( @Nullable Throwable throwable, Class<X> declaredType) throws X { propagateIfInstanceOf(throwable, declaredType); propagateIfPossible(throwable); }
/** * Propagates {@code throwable} as-is if it is an instance of {@link RuntimeException} or {@link * Error}, or else as a last resort, wraps it in a {@code RuntimeException} and then propagates. * <p> * This method always throws an exception. The {@code RuntimeException} return type is only for * client code to make Java type system happy in case a return value is required by the enclosing * method. Example usage: * <pre> * T doSomething() { * try { * return someMethodThatCouldThrowAnything(); * } catch (IKnowWhatToDoWithThisException e) { * return handle(e); * } catch (Throwable t) { * throw Throwables.propagate(t); * } * } * </pre> * * @param throwable the Throwable to propagate * @return nothing will ever be returned; this return type is only for your convenience, as * illustrated in the example above */ public static RuntimeException propagate(Throwable throwable) { propagateIfPossible(checkNotNull(throwable)); throw new RuntimeException(throwable); }
/** * Closes all {@code Closeable} instances that have been added to this {@code Closer}. If an * exception was thrown in the try block and passed to one of the {@code exceptionThrown} methods, * any exceptions thrown when attempting to close a closeable will be suppressed. Otherwise, the * <i>first</i> exception to be thrown from an attempt to close a closeable will be thrown and any * additional exceptions that are thrown after that will be suppressed. */ @Override public void close() throws IOException { Throwable throwable = thrown; // close closeables in LIFO order while (!stack.isEmpty()) { Closeable closeable = stack.removeFirst(); try { closeable.close(); } catch (Throwable e) { if (throwable == null) { throwable = e; } else { suppressor.suppress(closeable, throwable, e); } } } if (thrown == null && throwable != null) { Throwables.propagateIfPossible(throwable, IOException.class); throw new AssertionError(throwable); // not possible } }
/** * Propagates {@code throwable} exactly as-is, if and only if it is an instance of {@link * RuntimeException}, {@link Error}, {@code declaredType1}, or {@code declaredType2}. In the * unlikely case that you have three or more declared checked exception types, you can handle them * all by invoking these methods repeatedly. See usage example in {@link * #propagateIfPossible(Throwable, Class)}. * * @param throwable the Throwable to possibly propagate * @param declaredType1 any checked exception type declared by the calling method * @param declaredType2 any other checked exception type declared by the calling method */ public static <X1 extends Throwable, X2 extends Throwable> void propagateIfPossible( @Nullable Throwable throwable, Class<X1> declaredType1, Class<X2> declaredType2) throws X1, X2 { checkNotNull(declaredType2); propagateIfInstanceOf(throwable, declaredType1); propagateIfPossible(throwable, declaredType2); }