aboutsummaryrefslogtreecommitdiff
path: root/guava/src/com/google/common/collect/Streams.java
diff options
context:
space:
mode:
Diffstat (limited to 'guava/src/com/google/common/collect/Streams.java')
-rw-r--r--guava/src/com/google/common/collect/Streams.java33
1 files changed, 31 insertions, 2 deletions
diff --git a/guava/src/com/google/common/collect/Streams.java b/guava/src/com/google/common/collect/Streams.java
index 0b6e88ce2..8209cedb5 100644
--- a/guava/src/com/google/common/collect/Streams.java
+++ b/guava/src/com/google/common/collect/Streams.java
@@ -148,11 +148,40 @@ public final class Streams {
return optional.isPresent() ? DoubleStream.of(optional.getAsDouble()) : DoubleStream.empty();
}
+ @SuppressWarnings("CatchingUnchecked") // sneaky checked exception
private static void closeAll(BaseStream<?, ?>[] toClose) {
+ // If one of the streams throws an exception, continue closing the others, then throw the
+ // exception later. If more than one stream throws an exception, the later ones are added to the
+ // first as suppressed exceptions. We don't catch Error on the grounds that it should be allowed
+ // to propagate immediately.
+ Exception exception = null;
for (BaseStream<?, ?> stream : toClose) {
- // TODO(b/80534298): Catch exceptions, rethrowing later with extras as suppressed exceptions.
- stream.close();
+ try {
+ stream.close();
+ } catch (Exception e) { // sneaky checked exception
+ if (exception == null) {
+ exception = e;
+ } else {
+ exception.addSuppressed(e);
+ }
+ }
+ }
+ if (exception != null) {
+ // Normally this is a RuntimeException that doesn't need sneakyThrow.
+ // But theoretically we could see sneaky checked exception
+ sneakyThrow(exception);
+ }
+ }
+
+ /** Throws an undeclared checked exception. */
+ private static void sneakyThrow(Throwable t) {
+ class SneakyThrower<T extends Throwable> {
+ @SuppressWarnings("unchecked") // not really safe, but that's the point
+ void throwIt(Throwable t) throws T {
+ throw (T) t;
+ }
}
+ new SneakyThrower<Error>().throwIt(t);
}
/**