[C#.NET] 重新引發例外的時機?

  • 4391
  • 0
  • C#
  • 2012-08-14

[C#.NET] 重新引發例外的時機?

續上篇,[C#.NET] 設計底層類別時,請勿過度使用例外攔截,我們瞭解拋出throw時會造成堆疊改變,但以下的情況則不同,

你可能會像我一樣遇到可愛的3rd供應商

image

 

拋出例外時,元件裡的例外一律都是寫著:

Error HRESULT E_FAIL has been returned from a call to a COM component.

image

無一例外。

天知道這是發生了什麼事,這是COM元件的標準例外訊息嗎??這樣的訊息並不能帶給我們任何的幫助。

 

這會導致在UI層,無法明確的告知客戶出了什麼問題

SNAGHTML122ac58f

 

如果你想要明確的把訊息加上去往上拋可以這樣做,重新引發例外。

{
    ConnectCompletedEventArgs e = new ConnectCompletedEventArgs();
    this._isConnected = false;
    string address = "192.168.2.121";
    this._reader.ReaderAddress = address;
    this._reader.ReaderPort = 8080;
    try
    {
        this._reader.Open();
        this._isConnected = true;
    }
    catch (COMException ex)
    {
        ex.Data.Add("Socket", string.Format("Don't Connect to {0}", address));
        throw ex;
    }
    finally
    {
        e.IsConnected = this._isConnected;
        this.OnConnect(e);
    }
}

SNAGHTML123714b7

 

在UI端就這樣用 ex.Data["Socket"].ToString()

{
    Middleware middleware = new Middleware();
    try
    {
        middleware.Connect();
    }
    catch (Exception ex)
    {
        string msg = string.Format("StackTrace:{0}\r\nMessage:{1}", ex.StackTrace, ex.Data["Socket"].ToString());
        MessageBox.Show(msg);
    }
}

SNAGHTML1237fb00

at RfidReader.IntelleflexReader.Connect() in C:\Users\gy\Desktop\LogLibrary\LogLibrary\Reader.cs:line 52
at RfidReader.Middleware.Connect() in C:\Users\gy\Desktop\LogLibrary\LogLibrary\Middleware.cs:line 30
at Demo.Form1.button1_Click(Object sender, EventArgs e) in C:\Users\gy\Desktop\LogLibrary\Demo\Form1.cs:line 26

 

因為重新引發例外,例外堆疊的行號也變了。

 

除了利用Data屬性外,也可以將原本的例外打包變成Inner Exception

{
    ConnectCompletedEventArgs e = new ConnectCompletedEventArgs();
    this._isConnected = false;
    string address = "192.168.2.121";
    this._reader.ReaderAddress = address;
    this._reader.ReaderPort = 8080;
    try
    {
        this._reader.Open();
        this._isConnected = true;
    }
    catch (COMException comException)
    {
        COMException exception = new COMException(string.Format("Don't Connect to {0}", address), comException);
        throw exception;
    }
    finally
    {
        e.IsConnected = this._isConnected;
        this.OnConnect(e);
    }
}

image

 

在UI端使用時就可以看到Inner Exception屬性就是原本COMException

{
    Middleware middleware = new Middleware();
    try
    {
        middleware.Connect();
    }
    catch (Exception ex)
    {
        string msg = string.Format("StackTrace:{0}\r\nMessage:{1}", ex.StackTrace, ex.Message);
        MessageBox.Show(msg);
    }
}

SNAGHTML1241be9d

 

當然,這也會造成堆疊行號錯誤,但有了正確的訊息。

SNAGHTML12435cfd

 

正確發生錯誤行號與正確訊息之間,我應該怎麼選才好呢??

ex.InnerException 其實就包有正確發生錯誤行號,把它挖出來就好了。

{
    Middleware middleware = new Middleware();
    try
    {
        middleware.Connect();
    }
    catch (Exception ex)
    {
        StringBuilder stackTrace = new StringBuilder();
        if (ex.InnerException != null)
        {
            stackTrace.AppendLine(ex.InnerException.StackTrace);
        }
        stackTrace.AppendLine(ex.StackTrace);

        string msg = string.Format("StackTrace:{0}\r\nMessage:{1}", stackTrace, ex.Message);
        MessageBox.Show(msg);
    }
}

SNAGHTML125c2220

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo