捕获程序未抛出的异常

 

  这段时间,Unity项目遇到问题,工程中有很多有问题的代码,调试的时候,这些代码理应抛出异常但是却没有,这是一个很恐怖的事情,因为你根本不知道你代码中有哪些不对,程序运行下来,就会遇到各种逻辑问题,查无对策。后来我研究了下,记录了下来

  在unity中,子线程下的异常,如果不加try catch,可能不会被unity正常捕获,故而你会不知道这里有异常 

  先举个栗子

    Thread t1,t2;
    List<int> list = null;
    void Start ()
    {

        try
        {

            t1 = new Thread(new ThreadStart(MyTest));
            t1.Start();
        }
        catch
        {

        }

    }

    void MyTest()
    {
        //输出异常 1
        list.Add(1);
        try
        {
            list.Add(1);
        }
       catch(Exception e)
       {
            //输出异常 2
            Debug.Log(e.ToString());
       }

    }

  这段代码对一个null的引用尝试读写,将会引发空引用异常。在我们调用start方法后,控制台理应在执行“输出异常1”和“输出异常2”的时候打印异常信息,但是事实上,unity控制台中什么信息都没打印。如果你把程序发布,后果是可想而知的。

  然后我尝试在"输出异常1"处加了断点

  程序执行到这里,调试程序直接“崩了”,所以这行的异常信息没有输出到控制台,程序也没有往下执行,下面的异常信息自然也不会输出到控制台。

  所以我猜测肯定是40行代码导致t1子线程出了问题,所以unity不能正常捕获这里的异常或者输出这里的异常信息.

  那么有没有什么办法让unity向我们报告这个异常信息呢?

  

    Thread t1;
    List<int> list = null;
    void Start ()
    {
        AppDomain app = AppDomain.CurrentDomain;
        app.UnhandledException += App1_UnhandledException;
        try
        {

            t1 = new Thread(new ThreadStart(MyTest));
            t1.Start();
        }
        catch
        {

        }

    }

    private void App1_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Debug.Log(e.ExceptionObject.ToString());
    }

    void MyTest()
    {
        //输出异常 1
        list.Add(1);
        try
        {
            list.Add(1);
        }
       catch(Exception e)
       {
            //输出异常 2
            Debug.Log(e.ToString());
       }

    }

  

  红色部分是我新添加的代码,测试运行,得到输出

System.NullReferenceException: Object reference not set to an instance of an object
  at Test.MyTest () [0x00008] in E:\Demo\New Unity Project 3\Assets\Test.cs:40
UnityEngine.Debug:Log(Object)
Test:App1_UnhandledException(Object, UnhandledExceptionEventArgs) (at Assets/Test.cs:33)

  我成功的打印出了异常,并获得了异常位置(Test.cs:33)。

  

  AppDomain 描述一个运用程序域,当程序某个异常没有被捕获的时候,UnhandledException事件就会调用。下面是这个API详细介绍.

  https://msdn.microsoft.com/zh-cn/library/system.appdomain.unhandledexception(v=vs.110).aspx

 

原文地址:https://www.cnblogs.com/ferryqiu/p/8137062.html

时间: 2024-10-09 00:35:26

捕获程序未抛出的异常的相关文章

『默哀』你的梦或许因为这个新闻而碎了【用你的程序语言 抛出一行异常】

对很多程序猿而言: 提升技术,构思产品,熬夜编码,拉到风投,艰苦创业,做大公司 —— 这是很多程序猿的梦想. 2017-09-09最新新闻 —— 你的梦或许碎了: <传WePhone创始人自杀,去世前称被前妻勒索1000万> 立两个Flag先: > 新闻最新发生,目前民意是 95%支持 创业者.但!目测两天之内,其妻翟某某 就会请 水军 赶赴战场 —— 祸乱三观. > 逼丈夫自杀,目测 翟某某 可能会成为遗产继承人(如果离婚手续还没办完) —— 完蛋!逼死人的人,拿完 离婚协议款,

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

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

4.异常捕获后再次抛出

4.异常捕获后再次抛出 情况一:捕获后抛出原来的异常,希望保留最新的异常抛出点--fillStackTrace 情况二:捕获后抛出新的异常,希望抛出完整的异常链--initCause 1.捕获后重新抛出捕获的异常 在函数中捕获了异常,在catch模块中不做进一步的处理,而是向上一级进行传递 catch(Exception e){ throw e; } public class ReThrow { public static void f()throws Exception{ throw new

如何防止后台线程抛出的异常让程序崩溃退出

原文:如何防止后台线程抛出的异常让程序崩溃退出 如果你的程序抛了异常,你是怎么处理的呢?等待程序崩溃退出?还是进行补救? 如果是做 UI 开发,很容易就找到 Dispatcher.UnhandledException 事件,然后在事件中进行补救.如果补救成功,可以设置 e.Handled = true 来阻止异常继续让程序崩溃退出.但是,如果是后台线程抛出了异常呢?并没有 Dispatcher 可以用.所以我们就束手就擒让程序自己退出吗? WPF 和 Windows Forms 都是微软的框架,

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

finally中使用return会吃掉catch中抛出的异常

今天学习大神的文章:深入理解java异常处理机制 学到一个有意思的知识点.如果在finally中使用return会吃掉catch中抛出的异常. 看例子: [java] view plaincopy public class TestException { public TestException() { } boolean testEx() throws Exception { boolean ret = true; try { ret = testEx1(); } catch (Excepti

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

第六十二条:每个方法抛出的异常都要有文档

花点时间仔细为每个方法抛出的异常建立文档是特别重要的. 始终要单独的声明受检的异常,并且利用Javadoc的@throws标记,准确的记录下抛出每个异常的条件. 如果一个方法可能抛出多个受检异常,则不要使用"快捷方式"声明这个方法会抛出这些异常类的超类,如永远不要声明一个方法"throws Exception", 或者更糟糕的是声明这个方法"throws Throwable".因为这样的声明不仅没有为程序员提供关于"这个方法能够抛出哪些

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