[C#.NET] 重新引發例外的時機?
續上篇,[C#.NET] 設計底層類別時,請勿過度使用例外攔截,我們瞭解拋出throw時會造成堆疊改變,但以下的情況則不同,
你可能會像我一樣遇到可愛的3rd供應商
拋出例外時,元件裡的例外一律都是寫著:
Error HRESULT E_FAIL has been returned from a call to a COM component.
無一例外。
天知道這是發生了什麼事,這是COM元件的標準例外訊息嗎??這樣的訊息並不能帶給我們任何的幫助。
這會導致在UI層,無法明確的告知客戶出了什麼問題。
如果你想要明確的把訊息加上去往上拋可以這樣做,重新引發例外。
{
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);
}
}
在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);
}
}
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);
}
}
在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);
}
}
當然,這也會造成堆疊行號錯誤,但有了正確的訊息。
正確發生錯誤行號與正確訊息之間,我應該怎麼選才好呢??
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);
}
}
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET