我尝试在数据库服务器关闭时捕获数据库异常。我们使用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 :(得分:6)
Catch
处理已抛出的实际异常的类型,而GetBaseException
返回(第一个)InnerException
(如果存在)。
打印出实际的异常以查看其特定类型(或在调试器中检查它,或者其他)然后捕获它。
答案 1 :(得分:4)
因为抛出的东西不是SAException。尝试直接打印出异常而不是调用GetBaseException()。
答案 2 :(得分:3)
这不是SAException,这是内部异常。从堆栈跟踪中不清楚外部异常类型是什么。使用调试器或某些诊断代码很容易找到:
catch (Exception ex) {
Console.WriteLine(ex.GetType().FullName;
//...
}
答案 3 :(得分:1)
检查您遇到的实际异常情况。您的GetBaseException()
调用可能会掩盖正在发生的实际异常。
答案 4 :(得分: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
更改为特定的特定类型来改进此。