99
1010package org .elasticsearch .core ;
1111
12- import java .io .IOException ;
13- import java .io .UncheckedIOException ;
1412import java .util .Arrays ;
1513import java .util .Iterator ;
1614import java .util .concurrent .atomic .AtomicReference ;
@@ -21,11 +19,17 @@ public enum Releasables {
2119
2220 /** Release the provided {@link Releasable}s. */
2321 public static void close (Iterable <? extends Releasable > releasables ) {
24- try {
25- // this does the right thing with respect to add suppressed and not wrapping errors etc.
26- IOUtils .close (releasables );
27- } catch (IOException e ) {
28- throw new UncheckedIOException (e );
22+ RuntimeException firstException = null ;
23+ for (final Releasable releasable : releasables ) {
24+ try {
25+ close (releasable );
26+ } catch (RuntimeException e ) {
27+ firstException = useOrSuppress (firstException , e );
28+ }
29+ }
30+
31+ if (firstException != null ) {
32+ throw firstException ;
2933 }
3034 }
3135
@@ -38,7 +42,18 @@ public static void close(@Nullable Releasable releasable) {
3842
3943 /** Release the provided {@link Releasable}s. */
4044 public static void close (Releasable ... releasables ) {
41- close (true , releasables );
45+ RuntimeException firstException = null ;
46+ for (final Releasable releasable : releasables ) {
47+ try {
48+ close (releasable );
49+ } catch (RuntimeException e ) {
50+ firstException = useOrSuppress (firstException , e );
51+ }
52+ }
53+
54+ if (firstException != null ) {
55+ throw firstException ;
56+ }
4257 }
4358
4459 /** Release the provided {@link Releasable}s expecting no exception to by thrown by any of them. */
@@ -63,19 +78,21 @@ public static void closeExpectNoException(Releasable releasable) {
6378
6479 /** Release the provided {@link Releasable}s, ignoring exceptions. */
6580 public static void closeWhileHandlingException (Releasable ... releasables ) {
66- close (false , releasables );
81+ for (final Releasable releasable : releasables ) {
82+ try {
83+ close (releasable );
84+ } catch (RuntimeException e ) {
85+ // ignored
86+ }
87+ }
6788 }
6889
69- /** Release the provided {@link Releasable}s, ignoring exceptions if <code>success</code> is {@code false}. */
70- private static void close (boolean success , Releasable ... releasables ) {
71- try {
72- // this does the right thing with respect to add suppressed and not wrapping errors etc.
73- IOUtils .close (releasables );
74- } catch (IOException e ) {
75- if (success ) {
76- throw new UncheckedIOException (e );
77- }
90+ private static RuntimeException useOrSuppress (RuntimeException firstException , RuntimeException e ) {
91+ if (firstException == null || firstException == e ) {
92+ return e ;
7893 }
94+ firstException .addSuppressed (e );
95+ return firstException ;
7996 }
8097
8198 /** Wrap several releasables into a single one. This is typically useful for use with try-with-resources: for example let's assume
0 commit comments