public static Throwable findException(Object exception) {
    if (exception == null || !(exception instanceof Throwable)) {
      return null;
    }
    Throwable cur = (Throwable) exception;
    while (cur != null) {
      if (isSpecialException(cur)) {
        return cur;
      }
      if (cur instanceof RemoteException) {
        RemoteException re = (RemoteException) cur;
        cur = re.unwrapRemoteException();

        // unwrapRemoteException can return the exception given as a parameter when it cannot
        // unwrap it. In this case, there is no need to look further
        // noinspection ObjectEquality
        if (cur == re) {
          return cur;
        }

        // When we receive RemoteException which wraps IOException which has a cause as
        // RemoteException we can get into infinite loop here; so if the cause of the exception
        // is RemoteException, we shouldn't look further.
      } else if (cur.getCause() != null && !(cur.getCause() instanceof RemoteException)) {
        cur = cur.getCause();
      } else {
        return cur;
      }
    }

    return null;
  }
Look for an exception we know in the remote exception: - hadoop.ipc wrapped exceptions - nested
exceptions Looks for: RegionMovedException / RegionOpeningException / RegionTooBusyException /
RpcThrottlingException
@return null if we didn't find the exception, the exception otherwise.
hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/ClientExceptionsUtil.java