Skip to content

Commit 832db83

Browse files
CR: reuse existing approach
1 parent ff2ced3 commit 832db83

File tree

1 file changed

+27
-34
lines changed

1 file changed

+27
-34
lines changed

server/src/main/java/org/elasticsearch/ExceptionsHelper.java

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@
3838
import java.util.Arrays;
3939
import java.util.Collections;
4040
import java.util.HashSet;
41-
import java.util.IdentityHashMap;
4241
import java.util.LinkedList;
4342
import java.util.List;
4443
import java.util.Objects;
4544
import java.util.Optional;
4645
import java.util.Queue;
4746
import java.util.Set;
47+
import java.util.function.Predicate;
4848
import java.util.stream.Collectors;
4949

5050
public final class ExceptionsHelper {
@@ -186,27 +186,14 @@ public static <T extends Throwable> T useOrSuppress(T first, T second) {
186186
* @return Corruption indicating exception if one is found, otherwise {@code null}
187187
*/
188188
public static IOException unwrapCorruption(Throwable t) {
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-
}
189+
return t == null ? null : ExceptionsHelper.<IOException>unwrap(t, logger, cause -> {
197190
for (Class<?> clazz : CORRUPTION_EXCEPTIONS) {
198-
if (clazz.isInstance(t)) {
199-
return (IOException) t;
191+
if (clazz.isInstance(cause)) {
192+
return true;
200193
}
201194
}
202-
for (Throwable suppressed : t.getSuppressed()) {
203-
IOException corruptionException = doUnwrapCorruption(suppressed, seen);
204-
if (corruptionException != null) {
205-
return corruptionException;
206-
}
207-
}
208-
} while ((t = t.getCause()) != null);
209-
return null;
195+
return false;
196+
}).orElse(null);
210197
}
211198

212199
/**
@@ -219,9 +206,11 @@ private static IOException doUnwrapCorruption(Throwable t, Set<Throwable> seen)
219206
*/
220207
public static Throwable unwrap(Throwable t, Class<?>... clazzes) {
221208
if (t != null) {
222-
final Set<Throwable> seen = Collections.newSetFromMap(new IdentityHashMap<>());
209+
int iterations = 0;
223210
do {
224-
if (seen.add(t) == false) {
211+
++iterations;
212+
if (iterations > MAX_ITERATIONS) {
213+
logger.warn("giving up looking for nested cause", t);
225214
return null;
226215
}
227216
for (Class<?> clazz : clazzes) {
@@ -258,16 +247,10 @@ public static boolean reThrowIfNotNull(@Nullable Throwable e) {
258247

259248
static final int MAX_ITERATIONS = 1024;
260249

261-
/**
262-
* Unwrap the specified throwable looking for any suppressed errors or errors as a root cause of the specified throwable.
263-
*
264-
* @param cause the root throwable
265-
* @return an optional error if one is found suppressed or a root cause in the tree rooted at the specified throwable
266-
*/
267-
public static Optional<Error> maybeError(final Throwable cause, final Logger logger) {
268-
// early terminate if the cause is already an error
269-
if (cause instanceof Error) {
270-
return Optional.of((Error) cause);
250+
@SuppressWarnings("unchecked")
251+
private static <T extends Throwable> Optional<T> unwrap(Throwable cause, Logger logger, Predicate<Throwable> predicate) {
252+
if (predicate.test(cause)) {
253+
return Optional.of((T) cause);
271254
}
272255

273256
final Queue<Throwable> queue = new LinkedList<>();
@@ -277,12 +260,12 @@ public static Optional<Error> maybeError(final Throwable cause, final Logger log
277260
iterations++;
278261
// this is a guard against deeply nested or circular chains of exceptions
279262
if (iterations > MAX_ITERATIONS) {
280-
logger.warn("giving up looking for fatal errors", cause);
263+
logger.warn("giving up looking for nested cause", cause);
281264
break;
282265
}
283266
final Throwable current = queue.remove();
284-
if (current instanceof Error) {
285-
return Optional.of((Error) current);
267+
if (predicate.test(current)) {
268+
return Optional.of((T) current);
286269
}
287270
Collections.addAll(queue, current.getSuppressed());
288271
if (current.getCause() != null) {
@@ -292,6 +275,16 @@ public static Optional<Error> maybeError(final Throwable cause, final Logger log
292275
return Optional.empty();
293276
}
294277

278+
/**
279+
* Unwrap the specified throwable looking for any suppressed errors or errors as a root cause of the specified throwable.
280+
*
281+
* @param cause the root throwable
282+
* @return an optional error if one is found suppressed or a root cause in the tree rooted at the specified throwable
283+
*/
284+
public static Optional<Error> maybeError(final Throwable cause, final Logger logger) {
285+
return unwrap(cause, logger, t -> t instanceof Error);
286+
}
287+
295288
/**
296289
* See {@link #maybeError(Throwable, Logger)}. Uses the class-local logger.
297290
*/

0 commit comments

Comments
 (0)