HBASE-26688 Threads shared EMPTY_RESULT may lead to unexpected client job down. ...
[hbase.git] / hbase-client / src / main / java / org / apache / hadoop / hbase / exceptions / ClientExceptionsUtil.java
blob2482a632ca8d3c7a7fa15fb7153d0609bdd721b8
1 /*
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 package org.apache.hadoop.hbase.exceptions;
22 import java.io.EOFException;
23 import java.io.IOException;
24 import java.io.SyncFailedException;
25 import java.lang.reflect.UndeclaredThrowableException;
26 import java.net.ConnectException;
27 import java.net.SocketTimeoutException;
28 import java.nio.channels.ClosedChannelException;
29 import java.util.Set;
30 import java.util.concurrent.TimeoutException;
31 import org.apache.hadoop.hbase.CallDroppedException;
32 import org.apache.hadoop.hbase.CallQueueTooBigException;
33 import org.apache.hadoop.hbase.DoNotRetryIOException;
34 import org.apache.hadoop.hbase.MultiActionResultTooLarge;
35 import org.apache.hadoop.hbase.NotServingRegionException;
36 import org.apache.hadoop.hbase.RegionTooBusyException;
37 import org.apache.hadoop.hbase.RetryImmediatelyException;
38 import org.apache.hadoop.hbase.ipc.CallTimeoutException;
39 import org.apache.hadoop.hbase.ipc.FailedServerException;
40 import org.apache.hadoop.hbase.quotas.RpcThrottlingException;
41 import org.apache.hadoop.ipc.RemoteException;
42 import org.apache.yetus.audience.InterfaceAudience;
43 import org.apache.yetus.audience.InterfaceStability;
45 import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableSet;
47 @InterfaceAudience.Private
48 @InterfaceStability.Evolving
49 public final class ClientExceptionsUtil {
51 private ClientExceptionsUtil() {}
53 public static boolean isMetaClearingException(Throwable cur) {
54 cur = findException(cur);
56 if (cur == null) {
57 return true;
59 return !isSpecialException(cur) || (cur instanceof RegionMovedException)
60 || cur instanceof NotServingRegionException;
63 public static boolean isSpecialException(Throwable cur) {
64 return (cur instanceof RegionMovedException || cur instanceof RegionOpeningException
65 || cur instanceof RegionTooBusyException || cur instanceof RpcThrottlingException
66 || cur instanceof MultiActionResultTooLarge || cur instanceof RetryImmediatelyException
67 || cur instanceof CallQueueTooBigException || cur instanceof CallDroppedException
68 || cur instanceof NotServingRegionException || cur instanceof RequestTooBigException);
72 /**
73 * Look for an exception we know in the remote exception:
74 * - hadoop.ipc wrapped exceptions
75 * - nested exceptions
77 * Looks for: RegionMovedException / RegionOpeningException / RegionTooBusyException /
78 * RpcThrottlingException
79 * @return null if we didn't find the exception, the exception otherwise.
81 public static Throwable findException(Object exception) {
82 if (exception == null || !(exception instanceof Throwable)) {
83 return null;
85 Throwable cur = (Throwable) exception;
86 while (cur != null) {
87 if (isSpecialException(cur)) {
88 return cur;
90 if (cur instanceof RemoteException) {
91 RemoteException re = (RemoteException) cur;
92 cur = re.unwrapRemoteException();
94 // unwrapRemoteException can return the exception given as a parameter when it cannot
95 // unwrap it. In this case, there is no need to look further
96 // noinspection ObjectEquality
97 if (cur == re) {
98 return cur;
101 // When we receive RemoteException which wraps IOException which has a cause as
102 // RemoteException we can get into infinite loop here; so if the cause of the exception
103 // is RemoteException, we shouldn't look further.
104 } else if (cur.getCause() != null && !(cur.getCause() instanceof RemoteException)) {
105 cur = cur.getCause();
106 } else {
107 return cur;
111 return null;
115 * Checks if the exception is CallQueueTooBig exception (maybe wrapped
116 * into some RemoteException).
117 * @param t exception to check
118 * @return true if it's a CQTBE, false otherwise
120 public static boolean isCallQueueTooBigException(Throwable t) {
121 t = findException(t);
122 return (t instanceof CallQueueTooBigException);
126 * Checks if the exception is CallDroppedException (maybe wrapped
127 * into some RemoteException).
128 * @param t exception to check
129 * @return true if it's a CQTBE, false otherwise
131 public static boolean isCallDroppedException(Throwable t) {
132 t = findException(t);
133 return (t instanceof CallDroppedException);
136 // This list covers most connectivity exceptions but not all.
137 // For example, in SocketOutputStream a plain IOException is thrown at times when the channel is
138 // closed.
139 private static final ImmutableSet<Class<? extends Throwable>> CONNECTION_EXCEPTION_TYPES =
140 ImmutableSet.of(SocketTimeoutException.class, ConnectException.class,
141 ClosedChannelException.class, SyncFailedException.class, EOFException.class,
142 TimeoutException.class, TimeoutIOException.class, CallTimeoutException.class,
143 ConnectionClosingException.class, FailedServerException.class,
144 ConnectionClosedException.class);
147 * For test only. Usually you should use the {@link #isConnectionException(Throwable)} method
148 * below.
150 public static Set<Class<? extends Throwable>> getConnectionExceptionTypes() {
151 return CONNECTION_EXCEPTION_TYPES;
155 * Check if the exception is something that indicates that we cannot contact/communicate with the
156 * server.
157 * @param e exception to check
158 * @return true when exception indicates that the client wasn't able to make contact with server
160 public static boolean isConnectionException(Throwable e) {
161 if (e == null) {
162 return false;
164 for (Class<? extends Throwable> clazz : CONNECTION_EXCEPTION_TYPES) {
165 if (clazz.isAssignableFrom(e.getClass())) {
166 return true;
169 return false;
173 * Translates exception for preemptive fast fail checks.
174 * @param t exception to check
175 * @return translated exception
176 * @throws IOException
178 public static Throwable translatePFFE(Throwable t) throws IOException {
179 if (t instanceof NoSuchMethodError) {
180 // We probably can't recover from this exception by retrying.
181 throw (NoSuchMethodError) t;
184 if (t instanceof NullPointerException) {
185 // The same here. This is probably a bug.
186 throw (NullPointerException) t;
189 if (t instanceof UndeclaredThrowableException) {
190 t = t.getCause();
192 if (t instanceof RemoteException) {
193 t = ((RemoteException) t).unwrapRemoteException();
195 if (t instanceof DoNotRetryIOException) {
196 throw (DoNotRetryIOException) t;
198 if (t instanceof Error) {
199 throw (Error) t;
201 return t;