View Javadoc

1   /*
2    *
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
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
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.
18   */
19  
20  package org.apache.hadoop.hbase.exceptions;
21  
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.concurrent.TimeoutException;
30  
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.classification.InterfaceAudience;
39  import org.apache.hadoop.hbase.classification.InterfaceStability;
40  import org.apache.hadoop.hbase.ipc.CallTimeoutException;
41  import org.apache.hadoop.hbase.ipc.FailedServerException;
42  import org.apache.hadoop.hbase.quotas.RpcThrottlingException;
43  import org.apache.hadoop.hbase.quotas.ThrottlingException;
44  import org.apache.hadoop.ipc.RemoteException;
45  
46  @InterfaceAudience.Private
47  @InterfaceStability.Evolving
48  public final class ClientExceptionsUtil {
49  
50    private ClientExceptionsUtil() {}
51  
52    public static boolean isMetaClearingException(Throwable cur) {
53      cur = findException(cur);
54  
55      if (cur == null) {
56        return true;
57      }
58      return !isSpecialException(cur) || (cur instanceof RegionMovedException)
59          || cur instanceof NotServingRegionException;
60    }
61  
62    public static boolean isSpecialException(Throwable cur) {
63      return (cur instanceof RegionMovedException || cur instanceof RegionOpeningException
64          || cur instanceof RegionTooBusyException
65          || cur instanceof ThrottlingException || cur instanceof RpcThrottlingException
66          || cur instanceof MultiActionResultTooLarge || cur instanceof RetryImmediatelyException
67          || cur instanceof CallQueueTooBigException || cur instanceof CallDroppedException
68          || cur instanceof NotServingRegionException || cur instanceof RequestTooBigException);
69    }
70  
71  
72    /**
73     * Look for an exception we know in the remote exception:
74     * - hadoop.ipc wrapped exceptions
75     * - nested exceptions
76     *
77     * Looks for: RegionMovedException / RegionOpeningException / RegionTooBusyException /
78     *            ThrottlingException
79     * @return null if we didn't find the exception, the exception otherwise.
80     */
81    public static Throwable findException(Object exception) {
82      if (exception == null || !(exception instanceof Throwable)) {
83        return null;
84      }
85      Throwable cur = (Throwable) exception;
86      while (cur != null) {
87        if (isSpecialException(cur)) {
88          return cur;
89        }
90        if (cur instanceof RemoteException) {
91          RemoteException re = (RemoteException) cur;
92          cur = re.unwrapRemoteException();
93  
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;
99          }
100 
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;
108       }
109     }
110 
111     return null;
112   }
113 
114   /**
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
119    */
120   public static boolean isCallQueueTooBigException(Throwable t) {
121     t = findException(t);
122     return (t instanceof CallQueueTooBigException);
123   }
124 
125   /**
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
130    */
131   public static boolean isCallDroppedException(Throwable t) {
132     t = findException(t);
133     return (t instanceof CallDroppedException);
134   }
135 
136   /**
137    * Check if the exception is something that indicates that we cannot
138    * contact/communicate with the server.
139    *
140    * @param e exception to check
141    * @return true when exception indicates that the client wasn't able to make contact with server
142    */
143   public static boolean isConnectionException(Throwable e) {
144     if (e == null) {
145       return false;
146     }
147     // This list covers most connectivity exceptions but not all.
148     // For example, in SocketOutputStream a plain IOException is thrown
149     // at times when the channel is closed.
150     return (e instanceof SocketTimeoutException || e instanceof ConnectException
151       || e instanceof ClosedChannelException || e instanceof SyncFailedException
152       || e instanceof EOFException || e instanceof TimeoutException
153       || e instanceof CallTimeoutException || e instanceof ConnectionClosingException
154       || e instanceof FailedServerException);
155   }
156 
157   /**
158    * Translates exception for preemptive fast fail checks.
159    * @param t exception to check
160    * @return translated exception
161    * @throws IOException
162    */
163   public static Throwable translatePFFE(Throwable t) throws IOException {
164     if (t instanceof NoSuchMethodError) {
165       // We probably can't recover from this exception by retrying.
166       throw (NoSuchMethodError) t;
167     }
168 
169     if (t instanceof NullPointerException) {
170       // The same here. This is probably a bug.
171       throw (NullPointerException) t;
172     }
173 
174     if (t instanceof UndeclaredThrowableException) {
175       t = t.getCause();
176     }
177     if (t instanceof RemoteException) {
178       t = ((RemoteException) t).unwrapRemoteException();
179     }
180     if (t instanceof DoNotRetryIOException) {
181       throw (DoNotRetryIOException) t;
182     }
183     if (t instanceof Error) {
184       throw (Error) t;
185     }
186     return t;
187   }
188 }