2010-01-18 37 views
7

我有一些類其中,扔的時候,有一個比較深的InnerException樹工作。我想登錄並採取行動處理最具有問題真實原因的例外情況。找到最內層異常的正確方法?

我目前使用類似於

public static Exception getInnermostException(Exception e) { 
    while (e.InnerException != null) { 
     e = e.InnerException; 
    } 
    return e; 
} 

這是處理異常樹木的正確方法是什麼

+0

可能重複的[查找最內層的異常,而不使用while循環?](http://stackoverflow.com/questions/3876456/find-the-inner-most-exception-without-using- A-while循環) – DavidRR 2015-12-07 18:42:10

+0

如果有的話,它的另外一個重複的,這其中的老年人和有正確答案爲接受。 – 2015-12-08 11:26:38

+0

問題年齡並不總是指定重複的控制標準。例如,考慮另一個問題的數量是這個數字的十倍以上。另外,被接受的答案只反映了提問者的意見。最後,請注意,另一個問題的[最高投票答案](http://stackoverflow.com/a/5792456/1497596)也提供了'GetBaseException()',但是在某些情況下表明瞭它的侷限性。 – DavidRR 2015-12-08 13:15:15

回答

10

我想你可以用下面的代碼獲得最裏面的異常:

public static Exception getInnermostException(Exception e) { 
    return e.GetBaseException(); 
} 
+1

謝謝,我需要先閱讀更多API文檔,然後再提問:) – 2010-01-18 10:39:11

0

一句話,是的。我想不出任何明顯更好或不同的方法。除非你想把它作爲一個擴展方法來代替,但它實際上是六個,其他的是六個。

3

你可以使用GetBaseException方法。 非常快例如:

try 
{ 
    try 
    { 
     throw new ArgumentException("Innermost exception"); 
    } 
    catch (Exception ex) 
    { 
     throw new Exception("Wrapper 1",ex); 
    } 
} 
catch (Exception ex) 
{ 
    // Writes out the ArgumentException details 
    Console.WriteLine(ex.GetBaseException().ToString()); 
} 
+0

+1,我更喜歡其他答案,所以我才接受它。 – 2010-01-18 10:39:53

+0

夠公平的,不能與此爭論:)只是想我會舉一些示例代碼/測試工具來展示它的行動。 – AdaTheDev 2010-01-18 10:41:42

0

有跡象表明,可以有多個的根本原因(例如AggregateExceptionReflectionTypeLoadException)例外。

我創建了自己class導航樹,然後不同的訪問者吸引到收集全部或僅僅根源。樣本輸出here。下面的相關代碼片段。

public void Accept(ExceptionVisitor visitor) 
{ 
    Read(this.exception, visitor); 
} 

private static void Read(Exception ex, ExceptionVisitor visitor) 
{ 
    bool isRoot = ex.InnerException == null; 
    if (isRoot) 
    { 
     visitor.VisitRootCause(ex); 
    } 

    visitor.Visit(ex); 
    visitor.Depth++; 

    bool isAggregateException = TestComplexExceptionType<AggregateException>(ex, visitor, aggregateException => aggregateException.InnerExceptions); 
    TestComplexExceptionType<ReflectionTypeLoadException>(ex, visitor, reflectionTypeLoadException => reflectionTypeLoadException.LoaderExceptions); 

    // aggregate exceptions populate the first element from InnerExceptions, so no need to revisit 
    if (!isRoot && !isAggregateException) 
    { 
     visitor.VisitInnerException(ex.InnerException); 
     Read(ex.InnerException, visitor); 
    } 

    // set the depth back to current context 
    visitor.Depth--; 
} 

private static bool TestComplexExceptionType<T>(Exception ex, ExceptionVisitor visitor, Func<T, IEnumerable<Exception>> siblingEnumerator) where T : Exception 
{ 
    var complexException = ex as T; 
    if (complexException == null) 
    { 
     return false; 
    } 

    visitor.VisitComplexException(ex); 

    foreach (Exception sibling in siblingEnumerator.Invoke(complexException)) 
    { 
     visitor.VisitSiblingInnerException(sibling); 
     Read(sibling, visitor); 
    } 

    return true; 
} 
相關問題