Try-Catch沒法正肯定位異常位置,我推薦2個有效技巧

宇宙第一開發IDE Visual Studio的調試功能很是強大,日常工做debug幫助咱們解決很多問題。今天分享兩個異常捕獲的技巧,但願可以幫助解決一些問題。
如下兩種狀況,我相信你們都會遇到過。程序員

  • 1.沒有使用Try-Catch語句,當異常發生的時候,可以自動跳轉到異常發生的地方,在使用Try-Catch捕獲異常的時候,直接跳轉到Catch語句的位置,並不會自動定位到異常代碼的位置。
  • 2.使用Try-Catch的時候,多層方法調用時,並不能直接查看到異常代碼的位置。

技巧1:自動定位到異常代碼位置

針對問題1,咱們最想要的結果是,哪裏有代碼出現錯誤了,就直接定位到哪兒,異常出在哪行代碼上,我一眼就能看得出,這樣就能更快地處理問題了。
對於問題1,所出現的這種狀況,簡單復現一下一個空引用的異常dom

namespace ExceptionSample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Random random = null;
                Console.WriteLine(random.Next());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadLine();
        }
     }
}

上面的異常代碼NullReferrenceException,Debug模式下,會跳轉到catch語句這裏。你可能以爲這挺簡單的......可實際實際工做中,你的一個方法中僅僅只這一個對象嗎?
在這裏插入圖片描述
在實際工做中可能不止random一個對象,代碼複雜,對象夠多,幾十個也有,咱們就很難定位到異常出錯的代碼了。StackTrace能夠定位到那個函數調用錯了,並不能定位到哪一行代碼出錯了。
爲了解決這個行爲能夠經過在Visual Studio中菜單欄中的調試》窗口》異常設置中去配置。以下圖所示:
在這裏插入圖片描述
勾選上Common Language Runtime Exceptions下列的異常單選框。有點多,之前的設置有些變化。
如今咱們再看以前的代碼,使用Try-Catch語句捕獲異常的時候,就會直接定位到異常代碼的位置了,以下圖示:函數

static void Main(string[] args)
        {
            try
            {
                Random random = null;
                Random random1 = new Random();
                Random random2 = new Random();
                Random random3 = new Random();
                Console.WriteLine(random1.Next());
                Console.WriteLine(random2.Next());
                Console.WriteLine(random3.Next());
                Console.WriteLine(random.Next());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadLine();
        }

在這裏插入圖片描述

技巧2:正常的throw 姿式

仍是以前的一個方法,我已經將異常設置回覆默認了。spa

static void Main(string[] args)
        {
            try
            {
                Random random = null;
                Console.WriteLine(random.Next());
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.Write(ex);
                throw ex;
            }
        }

咱們再輸出中能夠看到(ps:項目名稱用的以前的,不介意哈)
在這裏插入圖片描述
錯誤的代碼在16行。可實際工做中的狀況並非這樣簡單,基本上是A方法調用B方法,B方法調用C方法,代碼以下所示:
在Main方法中調用ThrowNullReferrence(),方法ThrowNullReferrence中調用SetNullReferrence()。代碼變複雜後,一層嵌套一層。這個時候能正確顯示出代碼異常的位置嗎?debug

static void Main(string[] args)
        {
            try
            {
                ThrowNullReferrence();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.Write(ex);
                throw ex;
            }
        }
        public  static void ThrowNullReferrence()
        {
            try
            {
                SetNullReferrence();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.Write(ex);
                throw ex;
            }
        }
        public static void SetNullReferrence()
        {
            try {
                Random random = null;
                Console.WriteLine(random.Next());
            }
            catch(Exception ex)
            {
                System.Diagnostics.Debug.Write(ex);
                throw ex;
            }
        }

咱們能夠經過下圖看到:
在這裏插入圖片描述
System.NullReferenceException: 未將對象引用設置到對象的實例。
在 ExceptionSample.Program.SetNullReferrence() 位置 D:\Learn\延遲加載\LinqLayzLoad\LinqLayzLoad\Program.cs:行號 39System.NullReferenceException: 未將對象引用設置到對象的實例。
在 ExceptionSample.Program.SetNullReferrence() 位置 D:\Learn\延遲加載\LinqLayzLoad\LinqLayzLoad\Program.cs:行號 44
在 ExceptionSample.Program.ThrowNullReferrence() 位置 D:\Learn\延遲加載\LinqLayzLoad\LinqLayzLoad\Program.cs:行號 27System.NullReferenceException: 未將對象引用設置到對象的實例。
在 ExceptionSample.Program.ThrowNullReferrence() 位置 D:\Learn\延遲加載\LinqLayzLoad\LinqLayzLoad\Program.cs:行號 32
在 ExceptionSample.Program.Main(String[] args) 位置 D:\Learn\延遲加載\LinqLayzLoad\LinqLayzLoad\Program.cs:行號 153d

錯誤代碼的位置在39行,以上出現異常的地方都是throw的位置。
緣由呢?
catch捕獲完後,若是要向上拋出,應該從新實例化一個新的異常對象,再向上拋出,這個最外層方法catch到的纔是完整的異常,固然也包括完整的堆棧信息,這樣才能定位到異常代碼的位置。
要使用 throw new Exception
改造後的例子如圖,精準定位到
39行的空引用異常
Console.WriteLine(random.Next());
在這裏插入圖片描述調試

結語

分享以前看到的一個老程序員的經驗之談:「多coding,少debug」code

相關文章
相關標籤/搜索