连抛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

时间: 2024-08-05 18:34:39

连抛2个异常,第一个是第二个的Cause的相关文章

解决httpclient抛出URISyntaxException异常

这两天在使用httpclient发送http请求的时候,发现url中一旦包含某些特殊字符就会报错.抛出URISyntaxException异常,比如struts漏洞的利用url:(大括号就不行) redirect:${%23req%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest'),%23webroot%3d%23req.getSession().getServletContext().getReal

More Effective C++----(12)理解&quot;抛出一个异常&quot;与&quot;传递一个参数&quot;或&quot;调用一个虚函数&quot;间的差异

Item M12:理解"抛出一个异常"与"传递一个参数"或"调用一个虚函数"间的差异 从语法上看,在函数里声明参数与在catch子句中声明参数几乎没有什么差别: class Widget { ... }; //一个类,具体是什么类 // 在这里并不重要 void f1(Widget w); // 一些函数,其参数分别为 void f2(Widget& w); // Widget, Widget&,或 void f3(const W

druid抛出的异常------javax.management.InstanceAlreadyExistsException引发的一系列探索

最近项目中有个定时任务的需求,定时检查mysql数据与etcd数据的一致性,具体实现细节就不说了,今天要说的就是实现过程中遇到了druid抛出的异常,以及解决的过程 异常 异常详细信息 五月 05, 2017 4:16:00 下午 com.alibaba.druid.proxy.DruidDriver warn 警告: register druid-driver mbean error javax.management.InstanceAlreadyExistsException: com.al

捕获Java线程池执行任务抛出的异常

Java中线程执行的任务接口java.lang.Runnable 要求不抛出Checked异常, public interface Runnable { public abstract void run();} 那么如果 run() 方法中抛出了RuntimeException,将会怎么处理了? 通常java.lang.Thread对象运行设置一个默认的异常处理方法: java.lang.Thread.setDefaultUncaughtExceptionHandler(UncaughtExce

一个问题:关于finally中return吞掉catch块中抛出的异常

今天遇到一个感觉很神奇的问题,记录一下问题以及自己分析问题的思路. 预警:不知道怎么看java字节码的朋友可能需要先看一下如何阅读java字节码才能看懂后面的解释. 我有一段程序: public class Test { public static void main(String[] args) { try { int a = 1 / 0; } catch (Exception e) { throw e; } } } 这个程序的运行结果相信大家都能猜到: 在main方法里捕获异常没有处理直接往

try ,finally都抛出异常如何处理.如果try中抛出了异常,在控制权转移到调用栈上一层代码之前, finally 语句块也会执行,如果finally抛出异常,try语句快抛出的那个异常就

package com.github.jdk7; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * try ,finally都抛出异常如何处理.如果try中抛出了异常,在控制权转移到调用栈上一层代码之前, * finally 语句块也会执行,如果finally抛出异常,try语句快抛出的那个异常就丢失了. * * @author doctor * * @since 2014年

java 检查抛出的异常是否是要捕获的检查性异常或运行时异常或错误

/** * Return whether the given throwable is a checked exception: * that is, neither a RuntimeException nor an Error. * @param ex the throwable to check * @return whether the throwable is a checked exception * @see java.lang.Exception * @see java.lang

有时候在操作Session时,系统会抛出如下异常:java.lang.IllegalStateException: Cannot create a session after the response has been committed

有时候在操作Session时,系统会抛出如下异常 java.lang.IllegalStateException: Cannot create a session after the response has been committed 原因1: Session 的创建语句: HttpSession seesion = request.getSession(); 之前有Response的输出语句. 应该把HttpSession seesion = request.getSession(); 放

hadoop学习;hdfs操作;运行抛出权限异常: Permission denied;api查看源码方法;源码不停的向里循环;抽象类通过debug查找源码

eclipse快捷键alt+shift+m将选中的代码封装成方法:alt+shift+l将选中的代码添加对应类型放回参数 当调用一个陌生方法时,进入源码不停的向里循环,当找不到return类似方法的时候,可以看到最原始的方法 package com.kane.hdfs; import java.io.InputStream; import java.net.URL; import org.apache.hadoop.fs.FsUrlStreamHandlerFactory; import org

想抛就抛:Application_Error中统一处理ajax请求执行中抛出的异常

女朋友不是想抛就抛,但异常却可以,不信请往下看. 今天在MVC Controller中写代码时,纠结了一下: public async Task<ActionResult> Save(int? postId) { if(!IsOwner(postId.Value, userId)) { //抛不抛异常呢? } } 在这个地方要不要抛异常呢? 如果不抛异常,就得这么写: public async Task<ActionResult> Save(int? postId) { if(!I