content: /*
   * Copyright The OpenTelemetry Authors
   * SPDX-License-Identifier: Apache-2.0
   */
  
  package io.opentelemetry.instrumentation.api.instrumenter;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.UndeclaredThrowableException;
  import java.util.concurrent.ExecutionException;
  import javax.annotation.Nullable;
  
  final class DefaultErrorCauseExtractor implements ErrorCauseExtractor {
    static final ErrorCauseExtractor INSTANCE = new DefaultErrorCauseExtractor();
  
    @Nullable
    private static final Class<?> COMPLETION_EXCEPTION_CLASS = getCompletionExceptionClass();
  
    @Override
    public Throwable extract(Throwable error) {
      if (error.getCause() != null
          && (error instanceof ExecutionException
              || isInstanceOfCompletionException(error)
              || error instanceof InvocationTargetException
              || error instanceof UndeclaredThrowableException)) {
        return extract(error.getCause());
      }
      return error;
    }
  
    private static boolean isInstanceOfCompletionException(Throwable error) {
      return COMPLETION_EXCEPTION_CLASS != null && COMPLETION_EXCEPTION_CLASS.isInstance(error);
    }
  
    @Nullable
    private static Class<?> getCompletionExceptionClass() {
      try {
        return Class.forName("java.util.concurrent.CompletionException");
      } catch (ClassNotFoundException e) {
        // Android level 21 does not support java.util.concurrent.CompletionException
        return null;
      }
    }
  
    private DefaultErrorCauseExtractor() {}
  }
  