2011-09-06 46 views
6

我想拋出一個異常,但自定義消息並堅持棧跟蹤。我已經通過各種線程。拋出異常,但堅持堆棧跟蹤

catch (Exception ex) 
{ 
throw; // Message is read only but stacktrace persist 
throw ex; // Message is readonly and strack trace also blows .. worst! 
throw new CustomException("My exception");// Message can be overridden but stacktrace lost 
throw new CustomException("My message",ex);// same as above. However if this constructor in exception class calls same constructor of base class then .. see below 
} 

當最後appraoch使用(與自定義異常構造調用基類的構造函數),輸出對死亡的屏幕是一樣的東西:

**The remote server returned an error: (401) Unauthorized.** 

[WebException: The remote server returned an error: (401) Unauthorized.] 
original stack trace 

[NewException: newMessage] 
New Stack Trace 

的好處是一切都沒有在屏幕上。但是,最重要的是,我希望我的例外顯示「新消息」,而不是原始消息。

因此,調和我的問題:如何顯示在死亡的屏幕上的原始堆棧跟蹤,但與自定義錯誤消息?

+1

這是一個Web服務返回的異常? – Oded

+0

在我的例子中,它確實是一個web服務調用。然而,它是無關緊要的,因爲異常可能是像DivisionByZero或sqlException之類的東西。想法是讓用戶知道原始堆棧跟蹤,但是開發人員還可以自定義默認異常消息以獲得更多幫助。 – helloworld

+0

不,它並不重要。 Webservice框架對異常有自己的想法。 –

回答

8
throw new CustomException("My message",ex);// same as above (... stacktrace lost) 

您在評論中的結論是錯誤的最後一個。堆棧跟蹤保存在內部異常中。標準報告(包括Exception.ToString())將報告完整的堆棧跟蹤。這是當你獲得構造函數時你所看到的。 (始終呼叫正確的基地電話!)。

但我不承認[WebException]。在WCF你需要

<serviceDebug includeExceptionDetailInFaults="true"/> 

我想你的Web環境有一個類似的功能,抑制錯誤信息對客戶端。

3

使用你的第四種方法是它是如何通常完成和已建立的模式。您不應該將異常處理(或提升)與它們的顯示或記錄方式混淆起來,等等。

如果您控制了(捕獲)異常的輸出,即可以更改/編寫相應的代碼,您可以簡單地使用Exception.ToString()方法,該方法將打印外部異常,包括所有「內部」異常。

備註: 有時,內部異常不會由應用程序有意顯示。例如在WCF(Windows Communication Foundation)中,除非設置了IncludeExceptionDetails(通過配置,代碼...),否則內部異常甚至不會從服務器傳輸到客戶端。這通常是因爲內部異常被視爲實現細節,這可能會向攻擊者提供有價值的信息來破壞您的應用程序。

0

怎樣重寫StackTrace屬性?

class CustomException : Exception { 

    public CustomException(string message, Exception inner) : base(message, inner) { 
    } 

    public override string StackTrace { 
     get { 
      if (InnerException != null) { 
       return InnerException.StackTrace; 
      } 
      return base.StackTrace; 
     } 
    } 
} 
+0

謝謝!試過了......在顯示死亡的黃色屏幕時,InnerException.Stacktrace返回時被稱爲三次,每次顯示原始堆棧跟蹤。但奇怪的是,它仍然顯示新的堆棧軌跡:( – helloworld

+0

@enableDeepak:不知道它會導致宇宙崩潰在自己......對不起 –

0

我同意,選擇4通常是最好的......

然而,在開發過程中,我發現把整個catch子句用#if內(!DEBUG),以最終它非常有用外面(允許在調試模式下編譯):

#if (!DEBUG) 
catch (Exception ex) 
{ 
    // Catch logic for Release mode 
} 
#endif 
finally { } 

這使得代替在頂層,在發生錯誤的位置點的API突破。

只是不養成#if的習慣...在幾乎所有其他情況下,使用

[Conditional("DEBUG")] 

的方法,而不是前面