2011-01-11 13 views
5

Ich versuche, die Datenbankausnahme abzufangen, wenn der Datenbankserver ausgefallen ist. Wir verwenden Sybase IAnywhere.Warum kann die innere Ausnahme nicht gefunden werden?

Ich benutze reguläre C# try Fang, um den Namen der Datenbank Ausnahme zu bekommen.

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); 
} 

Die Ausnahme Ausdruck ist dies:

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) 

Also ich denke, das iAnywhere.Data.SQLAnywhere.SAException die wirkliche Ausnahme ist, sollte ich behandeln. Dann habe ich einen Haken für ihn:

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); 
} 

Aber die iAnywhere.Data.SQLAnywhere.SAException ist nicht gefangen. Ich bekomme immer noch die Exception gefangen. Warum?

+0

Können Sie auf "// code here" auch erweitern, ist dies der Code um Zeile 158 Ihrer app.xaml.cs Datei? – NotMe

+0

Sind Sie auch * sicher * das ist der verwendete Code? – NotMe

+0

"// code here" bedeutet Code für die Verbindung mit der Datenbank, um den Abruf durchzuführen. Und ich habe den DB-Server absichtlich abgeschaltet. So bekomme ich eine Ausnahme von der Datenbank. – 5YrsLaterDBA

Antwort

4

Weil was geworfen wird, ist keine SAException. Versuchen Sie, die Ausnahme direkt auszudrucken, anstatt GetBaseException() aufzurufen.

1

Überprüfen Sie, was die eigentliche Ausnahme ist, dass Sie durchkommen. Ihr GetBaseException() Aufruf maskiert möglicherweise die tatsächliche Ausnahme, die auftritt.

6

Catch befasst sich mit dem Typ der tatsächlichen Ausnahme, die geworfen wurde, während GetBaseException die (erste) InnerException zurückgibt, wenn vorhanden sind.

Drucken Sie die tatsächliche Ausnahme aus, um ihren spezifischen Typ zu sehen (oder untersuchen Sie sie in einem Debugger oder was auch immer) und fangen Sie dann das ab.

+3

Nicht die erste, die innerste –

+0

Ja - das ist eine semantisch korrekte Art und Weise, es zu sagen. +1 –

+0

Ah, jetzt sehe ich, wie du zuerst das gleiche Ding bedeuten kannst (das erste geworfen). Nun, auf jeden Fall keine Zweideutigkeit. –

3

Es ist nicht SAException, das ist die innere Ausnahme. Aus dem Stack-Trace ist nicht ersichtlich, was der äußere Ausnahme-Typ ist. Einfach mit dem Debugger, um herauszufinden, oder einem Diagnosecode:

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

Sie brauchen so etwas wie dies tun kann:

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

Wie die anderen Antworten angegeben haben, können Sie diese verbessern, wenn Sie das wissen Aktueller Typ der Ausnahme, indem Sie im obigen Code Exception in den spezifischen Typ der Ausnahme ändern.

Verwandte Themen