diff --git a/lucene/core/src/java/org/apache/lucene/util/IOUtils.java b/lucene/core/src/java/org/apache/lucene/util/IOUtils.java
index 766d6fb32ea..350ae432306 100644
--- a/lucene/core/src/java/org/apache/lucene/util/IOUtils.java
+++ b/lucene/core/src/java/org/apache/lucene/util/IOUtils.java
@@ -113,20 +113,32 @@ public final class IOUtils {
}
/**
- * Closes all given Closeables, suppressing all thrown exceptions.
+ * Closes all given Closeables, suppressing all thrown non {@link VirtualMachineError} exceptions.
+ * Even if a {@link VirtualMachineError} is thrown all given closeable are closed.
* @see #closeWhileHandlingException(Closeable...)
*/
public static void closeWhileHandlingException(Iterable extends Closeable> objects) {
+ VirtualMachineError firstError = null;
+ Throwable firstThrowable = null;
for (Closeable object : objects) {
try {
if (object != null) {
object.close();
}
} catch (VirtualMachineError e) {
- throw e;
+ firstError = useOrSuppress(firstError, e);
} catch (Throwable t) {
+ firstThrowable = useOrSuppress(firstThrowable, t);
}
}
+ if (firstError != null) {
+ // we ensure that we bubble up any errors. We can't recover from these but need to make sure they are
+ // bubbled up. if a non-VMError is thrown we also add the suppressed exceptions to it.
+ if (firstThrowable != null) {
+ firstError.addSuppressed(firstThrowable);
+ }
+ throw firstError;
+ }
}
/** adds a Throwable to the list of suppressed Exceptions of the first Throwable