LUCENE-8212: Ensure all closeables are closed even if an VMError is thrown

This commit is contained in:
Simon Willnauer 2018-03-21 09:35:15 +01:00
parent d2ef38d784
commit f664896d1f
1 changed files with 14 additions and 2 deletions

View File

@ -113,20 +113,32 @@ public final class IOUtils {
} }
/** /**
* Closes all given <tt>Closeable</tt>s, suppressing all thrown exceptions. * Closes all given <tt>Closeable</tt>s, suppressing all thrown non {@link VirtualMachineError} exceptions.
* Even if a {@link VirtualMachineError} is thrown all given closeable are closed.
* @see #closeWhileHandlingException(Closeable...) * @see #closeWhileHandlingException(Closeable...)
*/ */
public static void closeWhileHandlingException(Iterable<? extends Closeable> objects) { public static void closeWhileHandlingException(Iterable<? extends Closeable> objects) {
VirtualMachineError firstError = null;
Throwable firstThrowable = null;
for (Closeable object : objects) { for (Closeable object : objects) {
try { try {
if (object != null) { if (object != null) {
object.close(); object.close();
} }
} catch (VirtualMachineError e) { } catch (VirtualMachineError e) {
throw e; firstError = useOrSuppress(firstError, e);
} catch (Throwable t) { } 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 /** adds a Throwable to the list of suppressed Exceptions of the first Throwable