001/* 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020package org.apache.hadoop.hbase.exceptions; 021 022import java.io.EOFException; 023import java.io.IOException; 024import java.io.SyncFailedException; 025import java.lang.reflect.UndeclaredThrowableException; 026import java.net.ConnectException; 027import java.net.SocketTimeoutException; 028import java.nio.channels.ClosedChannelException; 029import java.util.concurrent.TimeoutException; 030 031import org.apache.hadoop.hbase.CallDroppedException; 032import org.apache.hadoop.hbase.CallQueueTooBigException; 033import org.apache.hadoop.hbase.DoNotRetryIOException; 034import org.apache.hadoop.hbase.MultiActionResultTooLarge; 035import org.apache.hadoop.hbase.NotServingRegionException; 036import org.apache.hadoop.hbase.RegionTooBusyException; 037import org.apache.hadoop.hbase.RetryImmediatelyException; 038import org.apache.yetus.audience.InterfaceAudience; 039import org.apache.yetus.audience.InterfaceStability; 040import org.apache.hadoop.hbase.ipc.CallTimeoutException; 041import org.apache.hadoop.hbase.ipc.FailedServerException; 042import org.apache.hadoop.hbase.quotas.RpcThrottlingException; 043import org.apache.hadoop.ipc.RemoteException; 044 045@InterfaceAudience.Private 046@InterfaceStability.Evolving 047public final class ClientExceptionsUtil { 048 049 private ClientExceptionsUtil() {} 050 051 public static boolean isMetaClearingException(Throwable cur) { 052 cur = findException(cur); 053 054 if (cur == null) { 055 return true; 056 } 057 return !isSpecialException(cur) || (cur instanceof RegionMovedException) 058 || cur instanceof NotServingRegionException; 059 } 060 061 public static boolean isSpecialException(Throwable cur) { 062 return (cur instanceof RegionMovedException || cur instanceof RegionOpeningException 063 || cur instanceof RegionTooBusyException || cur instanceof RpcThrottlingException 064 || cur instanceof MultiActionResultTooLarge || cur instanceof RetryImmediatelyException 065 || cur instanceof CallQueueTooBigException || cur instanceof CallDroppedException 066 || cur instanceof NotServingRegionException || cur instanceof RequestTooBigException); 067 } 068 069 070 /** 071 * Look for an exception we know in the remote exception: 072 * - hadoop.ipc wrapped exceptions 073 * - nested exceptions 074 * 075 * Looks for: RegionMovedException / RegionOpeningException / RegionTooBusyException / 076 * RpcThrottlingException 077 * @return null if we didn't find the exception, the exception otherwise. 078 */ 079 public static Throwable findException(Object exception) { 080 if (exception == null || !(exception instanceof Throwable)) { 081 return null; 082 } 083 Throwable cur = (Throwable) exception; 084 while (cur != null) { 085 if (isSpecialException(cur)) { 086 return cur; 087 } 088 if (cur instanceof RemoteException) { 089 RemoteException re = (RemoteException) cur; 090 cur = re.unwrapRemoteException(); 091 092 // unwrapRemoteException can return the exception given as a parameter when it cannot 093 // unwrap it. In this case, there is no need to look further 094 // noinspection ObjectEquality 095 if (cur == re) { 096 return cur; 097 } 098 099 // When we receive RemoteException which wraps IOException which has a cause as 100 // RemoteException we can get into infinite loop here; so if the cause of the exception 101 // is RemoteException, we shouldn't look further. 102 } else if (cur.getCause() != null && !(cur.getCause() instanceof RemoteException)) { 103 cur = cur.getCause(); 104 } else { 105 return cur; 106 } 107 } 108 109 return null; 110 } 111 112 /** 113 * Checks if the exception is CallQueueTooBig exception (maybe wrapped 114 * into some RemoteException). 115 * @param t exception to check 116 * @return true if it's a CQTBE, false otherwise 117 */ 118 public static boolean isCallQueueTooBigException(Throwable t) { 119 t = findException(t); 120 return (t instanceof CallQueueTooBigException); 121 } 122 123 /** 124 * Checks if the exception is CallDroppedException (maybe wrapped 125 * into some RemoteException). 126 * @param t exception to check 127 * @return true if it's a CQTBE, false otherwise 128 */ 129 public static boolean isCallDroppedException(Throwable t) { 130 t = findException(t); 131 return (t instanceof CallDroppedException); 132 } 133 134 /** 135 * Check if the exception is something that indicates that we cannot 136 * contact/communicate with the server. 137 * 138 * @param e exception to check 139 * @return true when exception indicates that the client wasn't able to make contact with server 140 */ 141 public static boolean isConnectionException(Throwable e) { 142 if (e == null) { 143 return false; 144 } 145 // This list covers most connectivity exceptions but not all. 146 // For example, in SocketOutputStream a plain IOException is thrown 147 // at times when the channel is closed. 148 return (e instanceof SocketTimeoutException || e instanceof ConnectException 149 || e instanceof ClosedChannelException || e instanceof SyncFailedException 150 || e instanceof EOFException || e instanceof TimeoutException 151 || e instanceof CallTimeoutException || e instanceof ConnectionClosingException 152 || e instanceof FailedServerException || e instanceof ConnectionClosedException); 153 } 154 155 /** 156 * Translates exception for preemptive fast fail checks. 157 * @param t exception to check 158 * @return translated exception 159 * @throws IOException 160 */ 161 public static Throwable translatePFFE(Throwable t) throws IOException { 162 if (t instanceof NoSuchMethodError) { 163 // We probably can't recover from this exception by retrying. 164 throw (NoSuchMethodError) t; 165 } 166 167 if (t instanceof NullPointerException) { 168 // The same here. This is probably a bug. 169 throw (NullPointerException) t; 170 } 171 172 if (t instanceof UndeclaredThrowableException) { 173 t = t.getCause(); 174 } 175 if (t instanceof RemoteException) { 176 t = ((RemoteException) t).unwrapRemoteException(); 177 } 178 if (t instanceof DoNotRetryIOException) { 179 throw (DoNotRetryIOException) t; 180 } 181 if (t instanceof Error) { 182 throw (Error) t; 183 } 184 return t; 185 } 186}