2011-01-11 7 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

"// 여기에서 코드를 확장 할 수 있습니까?"이 코드는 app.xaml.cs 파일의 158 행 주위에 있습니까? – NotMe

+0

또한 배포 된 코드입니까? – NotMe

+0

"// 여기에 코드"는 검색을 위해 데이터베이스에 연결하는 코드를 의미합니다. 그리고 목적에 따라 DB 서버를 종료했습니다. 그래서 나는 데이터베이스에서 예외를 얻을 것이다. – 5YrsLaterDBA

답변

4

Throw되는 것은 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을 예외의 특정 유형으로 변경하여 예외의 실제 유형

관련 문제