2011-01-11 10 views
5

データベースサーバーがダウンしているときにデータベースの例外をキャッチしようとしました。 Sybaseは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

"//ここでコードを展開できますか?これは、app.xaml.csファイルの158行目のコードですか? – NotMe

+0

また、これはデプロイされたコードですか? – NotMe

+0

"//ここにコードする"とは、取得するためにデータベースに接続するコードを意味します。そして私はdbサーバを目的に応じてシャットダウンします。だから私はデータベースから例外を得るでしょう。 – 5YrsLaterDBA

答えて

4

スローされるのはSAExceptionではないためです。 GetBaseException()を呼び出す代わりに直接例外を出力してみてください。

1

実際に例外が発生しているかどうかを確認してください。 GetBaseException()呼び出しが発生している実際の例外をマスクしている可能性があります。

6

Catchは、スローされた実際の例外の型を扱いますが、GetBaseExceptionは存在する場合は(InnerException)を返します。

実際の例外を表示して、特定のタイプを表示したり、デバッガで検査したり、それをキャッチしたりします。

+3

最初のものではなく、最も内側のもの –

+0

ええ、それはもっと意味的に正しい方法です。 +1 –

+0

ああ、今私はあなたが最初に同じもの(最初に投げられたもの)を意味する方法を見ています。まあ、いずれにしてもあいまいさはありません。 –

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を例外の特定のタイプに変更することにより、実際の例外のタイプを指定します。

関連する問題