38
38
import java .util .Arrays ;
39
39
import java .util .Collections ;
40
40
import java .util .HashSet ;
41
+ import java .util .IdentityHashMap ;
41
42
import java .util .LinkedList ;
42
43
import java .util .List ;
43
44
import java .util .Objects ;
@@ -185,21 +186,26 @@ public static <T extends Throwable> T useOrSuppress(T first, T second) {
185
186
* @return Corruption indicating exception if one is found, otherwise {@code null}
186
187
*/
187
188
public static IOException unwrapCorruption (Throwable t ) {
188
- if (t != null ) {
189
- do {
190
- for (Class <?> clazz : CORRUPTION_EXCEPTIONS ) {
191
- if (clazz .isInstance (t )) {
192
- return (IOException ) t ;
193
- }
189
+ return t == null ? null : doUnwrapCorruption (t , Collections .newSetFromMap (new IdentityHashMap <>()));
190
+ }
191
+
192
+ private static IOException doUnwrapCorruption (Throwable t , Set <Throwable > seen ) {
193
+ do {
194
+ if (seen .add (t ) == false ) {
195
+ return null ;
196
+ }
197
+ for (Class <?> clazz : CORRUPTION_EXCEPTIONS ) {
198
+ if (clazz .isInstance (t )) {
199
+ return (IOException ) t ;
194
200
}
195
- for ( Throwable suppressed : t . getSuppressed ()) {
196
- IOException corruptionException = unwrapCorruption ( suppressed );
197
- if ( corruptionException != null ) {
198
- return corruptionException ;
199
- }
201
+ }
202
+ for ( Throwable suppressed : t . getSuppressed ()) {
203
+ IOException corruptionException = doUnwrapCorruption ( suppressed , seen );
204
+ if ( corruptionException != null ) {
205
+ return corruptionException ;
200
206
}
201
- } while (( t = t . getCause ()) != null );
202
- }
207
+ }
208
+ } while (( t = t . getCause ()) != null );
203
209
return null ;
204
210
}
205
211
@@ -213,7 +219,11 @@ public static IOException unwrapCorruption(Throwable t) {
213
219
*/
214
220
public static Throwable unwrap (Throwable t , Class <?>... clazzes ) {
215
221
if (t != null ) {
222
+ final Set <Throwable > seen = Collections .newSetFromMap (new IdentityHashMap <>());
216
223
do {
224
+ if (seen .add (t ) == false ) {
225
+ return null ;
226
+ }
217
227
for (Class <?> clazz : clazzes ) {
218
228
if (clazz .isInstance (t )) {
219
229
return t ;
0 commit comments