连抛2个异常,第一个是第二个的Cause
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了连抛2个异常,第一个是第二个的Cause相关的知识,希望对你有一定的参考价值。
异常仅仅能抛一个,捕捉到再抛一个,也仅仅是一个异常
看以下的代码,假设你觉得运行不到(假设 if 条件满足)运行不到第2个 throwException 就错了 (Jeallybean code)
libcore/luni/src/main/native/libcore_io_Posix.cpp#throwException
146 static void throwGaiException(JNIEnv* env, const char* functionName, int error) { 147 if (errno != 0) { 148 // EAI_SYSTEM should mean "look at errno instead", but both glibc and bionic seem to 149 // mess this up. In particular, if you don‘t have INTERNET permission, errno will be EACCES 150 // but you‘ll get EAI_NONAME or EAI_NODATA. So we want our GaiException to have a 151 // potentially-relevant ErrnoException as its cause even if error != EAI_SYSTEM. 152 // http://code.google.com/p/android/issues/detail?id=15722 153 throwErrnoException(env, functionName); 154 // Deliberately fall through to throw another exception... 155 } 156 static jmethodID ctor3 = env->GetMethodID(JniConstants::gaiExceptionClass, 157 "<init>", "(Ljava/lang/String;ILjava/lang/Throwable;)V"); 158 static jmethodID ctor2 = env->GetMethodID(JniConstants::gaiExceptionClass, 159 "<init>", "(Ljava/lang/String;I)V"); 160 throwException(env, JniConstants::gaiExceptionClass, ctor3, ctor2, functionName, error); 161 }
由于这不是 native C++ 自己的exception。而是 native 送给 java 层的 exception
再看以下的函数,假设在有 Pending Exception 的情况下(env->ExceptionOccurred), Pending Exception 将成为当前Exception 的 cause
113 static void throwException(JNIEnv* env, jclass exceptionClass, jmethodID ctor3, jmethodID ctor2, 114 const char* functionName, int error) { 115 jthrowable cause = NULL; 116 if (env->ExceptionCheck()) { 117 cause = env->ExceptionOccurred(); 118 env->ExceptionClear(); 119 } 120 121 ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName)); 122 if (detailMessage.get() == NULL) { 123 // Not really much we can do here. We‘re probably dead in the water, 124 // but let‘s try to stumble on... 125 env->ExceptionClear(); 126 } 127 128 jobject exception; 129 if (cause != NULL) { 130 exception = env->NewObject(exceptionClass, ctor3, detailMessage.get(), error, cause); 131 } else { 132 exception = env->NewObject(exceptionClass, ctor2, detailMessage.get(), error); 133 } 134 env->Throw(reinterpret_cast<jthrowable>(exception)); 135 }
再看以下
libcore/luni/src/main/java/java/net/InetAddress.java#getAllByNameImpl
417 } catch (GaiException gaiException) { 418 // If the failure appears to have been a lack of INTERNET permission, throw a clear 419 // SecurityException to aid in debugging this common mistake. 420 // http://code.google.com/p/android/issues/detail?id=15722 421 if (gaiException.getCause() instanceof ErrnoException) { 422 if (((ErrnoException) gaiException.getCause()).errno == EACCES) { 423 throw new SecurityException("Permission denied (missing INTERNET permission?)", gaiException); 424 } 425 } 426 // Otherwise, throw an UnknownHostException. 427 String detailMessage = "Unable to resolve host \"" + host + "\": " + Libcore.os.gai_strerror(gaiException.error); 428 addressCache.putUnknownHost(host, detailMessage); 429 throw gaiException.rethrowAsUnknownHostException(detailMessage); 430 }
检測到GaiException的时候。正好检查 Cause 是否是 ErrnoException
以上是关于连抛2个异常,第一个是第二个的Cause的主要内容,如果未能解决你的问题,请参考以下文章
Reactjs-setState 前一个状态是第一个参数,props 作为第二个参数
想要使用 SharePreferences 更新第二个片段中的数据,但第二个片段没有更新
讲解下图中Simulink的product用法,尤其是第二个、第三个、第五个
关于 flutter_boost 实现 第一个fluter页面跳入第二个的时候 关闭第一个页面么 或者 第一个页面到第二个页面到第三个页面关闭前两个页面,场景有先登录页面 然后 跳主页 关闭 登录页