중첩 된 Try / Catch 블록이 나쁜 생각입니까?


81

다음과 같은 구조가 있다고 가정 해 보겠습니다.

Try
  ' Outer try code, that can fail with more generic conditions, 
  ' that I know less about and might not be able to handle

  Try
    ' Inner try code, that can fail with more specific conditions,
    ' that I probably know more about, and are likely to handle appropriately
  Catch innerEx as Exception
    ' Handle the inner exception
  End Try

Catch outerEx as Exception
  ' Handle outer exception
End Try

Try이와 같은 중첩 블록이 권장되지 않는다는 의견을 보았지만 구체적인 이유를 찾을 수 없었습니다.

이것은 잘못된 코드입니까? 그렇다면 그 이유는 무엇입니까?


2
스 니펫이 실제로 얼마나 정확한지 확실하지 않습니다. 그러나 예외를 포착했을 때 실제로 아는 엉뚱한 것은 없습니다. 그것은 무엇이든 될 수 있습니다 . VB.NET이 지원하는 When 절을 활용 해보십시오.
Hans Passant

답변:


85

예를 들어 예외를 처리하고 나머지 컬렉션을 계속 처리하려는 경우 전체 메서드에 대해 하나의 try / catch를 사용하고 루프 내부에 다른 하나를 시도하는 것과 같은 특정 상황이 있습니다.

실제로 그렇게하는 유일한 이유는 스택을 풀고 컨텍스트를 잃는 대신 오류가 발생한 비트를 건너 뛰고 계속 진행하려는 경우입니다. 편집기에서 여러 파일을 여는 것이 한 가지 예입니다.

즉, 예외는 (이름에서 알 수 있듯이) 예외적이어야합니다. 프로그램은이를 처리해야하지만 정상적인 실행 흐름의 일부로이를 피해야합니다. 대부분의 언어 에서 계산 비용이 많이 듭니다 (Python은 주목할만한 예외 중 하나입니다).

유용한 다른 기술 중 하나는 특정 예외 유형을 포착하는 것입니다.

Try
    'Some code to read from a file

Catch ex as IOException
    'Handle file access issues (possibly silently depending on usage)
Catch ex as Exception
    ' Handle all other exceptions.
    ' If you've got a handler further up, just omit this Catch and let the 
    ' exception propagate
    Throw
End Try

또한 오류 처리 루틴에서 중첩 된 try / catches를 사용합니다.

    Try
        Dim Message = String.Format("...", )
        Try
            'Log to database
        Catch ex As Exception
            'Do nothing
        End Try

        Try
            'Log to file
        Catch ex As Exception
            'Do nothing
        End Try
    Catch ex As Exception
        'Give up and go home
    End Try

7
백그라운드 스레드에 로그인하는 것은 내부 try / catch를 사용하는 곳입니다. 나는 그것이 무엇을하고 있는지를 문서화 할 수 없기 때문에 메소드가 끝나기를 원하지 않습니다.
gooch

@Gooch true, 나도 그렇게합니다. 내 대답에 추가하겠습니다.
Basic

37

나는 실제로 중첩 Try/ Catch블록 에 대해 본질적으로 잘못된 것이 없다고 생각하지만 , 탐색하기 어려울 수 있고 리팩토링 (예 : 내부 Try/ Catch자체 메서드)을 수행 할 수 있다는 신호일 가능성이 있습니다 .

그러나 나는이 코멘트를 다루고 싶다.

' Outer try code, that can fail with more generic conditions, 
' that I know less about and might not be able to handle

특정 상황에서 예외를 처리하는 방법을 모른다면 저를 믿으십시오. 예외를 포착 하지 마십시오 . 복구하는 방법을 모르는 무언가를 잡은 다음 앱이 손상된 상태에서 계속 즐겁게 진행되도록하는 것보다 앱이 충돌하도록하는 것이 좋습니다 (즉, 로그를 기록 하고 삼키지 마십시오). . 그 시점부터 행동은 기껏해야 예측할 수 없습니다.


사실입니다. 외부 예외를 포착하는 시점에서 계속하고 싶지 않습니다. 나는 응용 프로그램을 정상적으로 종료 / 다시 시작할 수 있고 "추한 충돌"으로 사용자에게 충격을주지 않을 수 있다고 생각했습니다.
Goro

10
@Goro :이 경우에는 Application.UnhandledException메서드 Try/ Catch블록 단위보다는 앱 전체의 예외 처리 메커니즘 (예 : WinForms 인 경우 이벤트 처리 )을 권장합니다 .
Dan Tao
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.