2011-01-11 51 views
5

我試圖捕捉數據庫服務器關閉時的數據庫異常。我們使用Sybase IAnywhere。爲什麼不能捕捉到內部異常?

我使用常規的C#try catch來獲取數據庫異常的名稱。

try 
{ 
//code here 
} 
catch (Exception ex) 
{ 
Logging.Log.logItem(LogType.Exception, "Exception in isDBRunning", "App_Startup::isDBRunning() ", "GetBaseException=" + ex.GetBaseException().ToString() + "\nMessage=" + ex.Message + "\nStackTrace: " + ex.StackTrace + "\nInnerException: " + ex.InnerException); 
} 

例外打印出來是這樣的:

GetBaseException=iAnywhere.Data.SQLAnywhere.SAException: Database server not found 
    at iAnywhere.Data.SQLAnywhere.SAConnection.Open() 
    at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) 
Message=The underlying provider failed on Open. 
StackTrace: at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) 
    at System.Data.EntityClient.EntityConnection.Open() 
    at System.Data.Objects.ObjectContext.EnsureConnection() 
    at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) 
    at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() 
    at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source) 
    at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__2[TResult](IEnumerable`1 sequence) 
    at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot) 
    at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression) 
    at System.Linq.Queryable.Count[TSource](IQueryable`1 source) 
    at Analogic.SystemSoftware.App.isDBRunning() in C:\workspace\SystemSoftware\SystemSoftware\src\startup\App.xaml.cs:line 158 
InnerException: iAnywhere.Data.SQLAnywhere.SAException: Database server not found 
    at iAnywhere.Data.SQLAnywhere.SAConnection.Open() 
    at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) 

所以我覺得iAnywhere.Data.SQLAnywhere.SAException是真正的例外,我應該處理。然後我添加了一個捕獲它:

try 
{ 
//code here 
} 
catch (iAnywhere.Data.SQLAnywhere.SAException ex) 
{ 
Logging.Log.logItem(LogType.Exception, "Exception in isDBRunning 1", "App_Startup::isDBRunning() ", "GetBaseException=" + ex.GetBaseException().ToString() + "\nMessage=" + ex.Message + "\nStackTrace: " + ex.StackTrace + "\nInnerException: " + ex.InnerException); 
} 

catch (Exception ex) 
{ 
Logging.Log.logItem(LogType.Exception, "Exception in isDBRunning", "App_Startup::isDBRunning() ", "GetBaseException=" + ex.GetBaseException().ToString() + "\nMessage=" + ex.Message + "\nStackTrace: " + ex.StackTrace + "\nInnerException: " + ex.InnerException); 
} 

iAnywhere.Data.SQLAnywhere.SAException不被捕獲。我仍然抓到Exception。爲什麼?

+0

你可以擴展「// code here」嗎?這是圍繞你的app.xaml.cs文件的第158行的代碼嗎? – NotMe 2011-01-11 15:59:37

+0

另外,你是否確定這是部署的代碼? – NotMe 2011-01-11 16:00:58

回答

4

因爲拋出的不是SAException。嘗試直接打印出異常,而不是調用GetBaseException()。

1

檢查看看你有什麼實際例外。您的GetBaseException()調用可能會掩蓋正在發生的實際異常。

6

Catch處理拋出的實際異常的類型,而GetBaseException返回(第一個)InnerException(如果存在)。

打印出實際的異常以查看其特定類型(或者在調試器中檢查它,或其他),然後捕獲它。

3

這不是SAException,這是內部異常。從堆棧跟蹤中不清楚外部異常類型是什麼。不難看出與調試器或一些診斷代碼:

catch (Exception ex) { 
    Console.WriteLine(ex.GetType().FullName; 
    //... 
} 
1

你可能需要做這樣的事情:

try 
{ 
    //code here 
} 
catch (Exception ex) 
{ 
    if (ex.GetBaseException() is iAnywhere.Data.SQLAnywhere.SAException) 
    { 
     // log or handle known exception 
    } 
    else 
    { 
     // log unexpected exception 
    } 
} 

至於其他的答案都表示,可以提高這個,如果你知道通過將上述代碼中的Exception更改爲特定類型的例外,可以確定例外的實際類型。