在軟件開發過程中,我們經常會遇到異常情況。當異常發生時,了解異常的詳細信息和它的內部異常(Inner Exception)是非常重要的。內部異常提供了異常鏈中更深層次的上下文,幫助我們更好地理解和解決問題。本文將介紹一種方法,通過使用DeepLogInvocationException函數,可以方便地記錄並查看異常鏈中每個內部異常的詳細信息。
在Unity 2021.2.0a11版本中,我們可以利用其特性,直接在Unity3D控制台中打開與異常相關的文件,並跳轉到異常發生的行號。這為我們調試異常提供了便利。
首先,我們來看一下Hyperlink函數的實現。它是一個擴展方法,用於將文本標記為超鏈接並提供鏈接地址。在我們的方法中,我們使用了兩個重載:
public static string Hyperlink(this string tag, string url) { return $"<a href=\"{url}\">{tag}</a>"; } public static string Hyperlink(this string tag, string url, int line) { return $"<a href=\"{url}\" line=\"{line}\">{tag}</a>"; }
接下来,让我们看一下DeepLogInvocationException
函数的实现。它是一个扩展方法,用于在事件调度过程中调试异常。
public static void DeepLogInvocationException(this Exception ex, string delegateName, int skipDepth = 0) { int skip = Mathf.Max(0, skipDepth); int atLeastOne = 0; StringBuilder sb = new StringBuilder(); Exception orgEx = ex; while (ex is not null) { StackTrace trace = new(ex, true); if (skip <= 0) { var errorType = ex.GetType().Name; for (var i = 0; i < trace.FrameCount; ++i) { if (TryGetFrameInfo(trace.GetFrame(i), out var info)) { sb.AppendLine(info); } } AxDebug.LogError($"[{delegateName}] -> {errorType}:\n{ex.Message}\n{sb.ToString()}\n\n{ex.StackTrace}\n"); ++atLeastOne; } --skip; ex = ex.InnerException; } // Fall back when no exception was logged if (atLeastOne == 0) AxDebug.LogError($"Exception during {delegateName} < {orgEx.Message}\n{orgEx.StackTrace}\n"); bool TryGetFrameInfo(StackFrame frame, out string info) { info = null; if (frame == null) return false; var filePath = frame.GetFileName(); if (filePath == null || filePath.Length == 0) return false; var fileName = System.IO.Path.GetFileName(filePath); var lineNo = frame.GetFileLineNumber(); var methodName = frame.GetMethod().GetFullName(); var tag = $"{fileName} > {methodName}"; info = $"{tag.Hyperlink(filePath, lineNo)}:Line {lineNo}"; return true; } }
使用上述處理方式的好處和壞處如下:
好處:
詳細的異常信息:DeepLogInvocationException函數允許記錄異常鏈中每個內部異常的詳細信息,包括異常類型、消息和堆棧跟蹤。這樣可以提供更豐富的調試信息,幫助開發人員定位和解決問題。
異常調試的便利性:通過在Unity3D控制台中打開與異常相關的文件並跳轉到異常發生的行號,我們可以更方便地調試異常。這在復雜的代碼邏輯中特別有用,可以減少手動查找和追蹤異常的工作量。
內部異常的處理:異常鏈中的內部異常提供了更深層次的上下文信息,幫助我們了解異常的原因和發生位置。通過記錄並處理內部異常,我們可以更好地追蹤異常的源頭,並采取適當的措施進行修復。
壞處:
信息重復輸出:如果異常鏈較長且有多個內部異常,可能會導致重復輸出相同的異常信息。這可能會在日志中產生冗余信息,增加日志文件的大小。
可能影響性能:在遍歷異常鏈並記錄異常信息時,可能會引入一定的性能開銷。特別是在異常鏈較長或異常處理頻繁的情況下,可能會對應用程序的性能產生輕微影響。
綜上所述,使用DeepLogInvocationException函數可以提供更豐富的調試信息和異常處理能力,但需要注意避免冗余輸出和可能的性能影響。在開發過程中,根據具體情況和需求,可以權衡利弊並進行適當的使用和調整。