다음을 통해 공유


Try...Catch...Finally 문(Visual Basic)

이 문을 사용하면 코드를 실행하면서 특정 코드 블록에서 발생할 수 있는 오류의 일부 또는 전부를 처리할 수 있습니다.

Try
    [ tryStatements ]
    [ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
    [ catchStatements ]
    [ Exit Try ] ]
[ Catch ... ]
[ Finally
    [ finallyStatements ] ]
End Try

구성 요소

용어

내용

tryStatements

선택적 요소로서, 오류가 발생할 수 있는 문입니다. 복합 문도 가능합니다.

Catch

선택적 요소로서, 여러 Catch 블록을 사용할 수 있습니다. Try 블록을 처리하는 동안 예외가 발생하면 각 Catch 문을 텍스트 순서대로 검사하여 예외(throw된 예외를 나타내는 exception)를 처리했는지 여부를 확인합니다.

exception

선택적 요소로서, 임의의 변수 이름입니다. exception의 초기 값은 throw된 오류 값입니다. Catch와 함께 사용되어 catch된 예외를 지정합니다. 이를 생략하면 Catch 문에서 모든 예외를 catch합니다.

type

선택적 요소로서, 클래스 필터의 형식을 지정합니다. exception의 값이 type에 의해 지정된 형식이거나 파생 형식인 경우 식별자가 예외 개체에 바인딩됩니다.

When

선택적 요소로서, When 절이 있는 Catch 문은 expression이 True인 경우에만 예외를 catch합니다. When 절은 예외의 형식을 확인한 다음에만 적용되며 expression은 예외를 나타내는 식별자를 참조할 수도 있습니다.

expression

선택적 요소로서, Boolean으로 암시적으로 변환될 수 있어야 합니다. 일반 필터를 설명하는 임의의 식입니다. 일반적으로 오류 번호로 필터링하는 데 사용됩니다. When 키워드와 함께 사용되어 오류가 catch되는 상황을 지정합니다.

catchStatements

선택적 요소로서, 연결된 Try 블록에서 발생하는 오류를 처리하는 문입니다. 복합 문도 가능합니다.

Exit Try

선택적 요소로서, Try...Catch...Finally 구조를 중단하는 키워드입니다. End Try 문 바로 다음의 코드를 사용하여 실행을 다시 시작합니다. Finally 문도 여전히 실행됩니다. Finally 블록에서는 이 키워드를 사용할 수 없습니다.

Finally

선택적 요소로서, Finally 블록은 실행이 Try...Catch 문의 일부를 벗어날 때 항상 실행됩니다.

finallyStatements

선택적 요소로서, 다른 모든 오류 처리가 완료된 후 실행되는 문입니다.

End Try

Try...Catch...Finally 구조를 끝냅니다.

설명

특정 코드 섹션을 실행하는 동안 특정 예외가 발생할 수 있을 것으로 예상되는 경우에는 해당 코드를 Try 블록에 넣고 Catch 블록을 사용하여 예외 발생 시 제어를 유지하고 해당 예외를 처리합니다.

Try…Catch 문은 다양한 예외의 처리기를 지정하는 Try 블록과 하나 이상의 Catch 절로 구성되어 있습니다. Try 블록에 예외가 throw되면 Visual Basic은 예외를 처리하는 Catch 문을 검색합니다. 일치하는 Catch 문을 찾을 수 없는 경우 Visual Basic이 현재 메서드를 호출한 메서드부터 콜 스택까지 조사합니다. Catch 블록을 찾지 못하면 Visual Basic은 사용자에게 처리되지 않은 예외 메시지를 표시하고 프로그램 실행을 중지합니다.

Try…Catch 문에서 Catch 문을 두 개 이상 사용할 수 있습니다. 이렇게 할 경우 Catch 절은 순서대로 검사되므로 해당 절의 순서가 중요합니다. 보다 구체적인 예외를 먼저 catch하십시오.

다음 Catch 문 조건은 가장 일반적인 것이며 Exception 클래스에서 파생되는 모든 예외를 catch합니다. 이러한 종류의 Catch 문은 일반적으로 Catch 구조에서 예상되는 특정 예외를 모두 catch한 후에 마지막 Try...Catch...Finally 블록으로 사용해야 합니다. 제어 흐름은 이러한 변형 중 하나를 따르는 Catch 블록에 도달할 수 없습니다.

  • type은 Exception입니다(예: Catch ex As Exception).

  • 이 문에는 exception 변수가 없습니다(예: Catch).

Try…Catch…Finally 문이 다른 Try 블록에 중첩되어 있는 경우 Visual Basic은 가장 안쪽의 Try 블록에 있는 각 Catch 문을 먼저 검사합니다. 일치하는 Catch 문이 없을 경우 바깥쪽 Try…Catch…Finally 블록의 Catch 문으로 검색이 계속 진행됩니다.

Try 블록과 Catch 블록은 별개의 블록이므로 Try 블록의 지역 변수를 Catch 블록에 사용할 수 없습니다. 둘 이상의 블록에서 변수를 사용하려면 Try...Catch...Finally 구조의 외부에서 변수를 선언해야 합니다.

Try…Catch…Finally 문을 IntelliSense 코드 조각으로 사용할 수 있습니다. 코드 조각 관리자에서 코드 패턴 - If, For Each, Try Catch, Property 등을 확장한 다음 오류 처리(예외)를 확장합니다. 자세한 내용은 방법: IntelliSense 코드 조각 삽입을 참조하십시오.

Finally 블록

Try 구조체를 끝내기 전에 실행할 문이 하나 이상 있으면 Finally 블록을 사용합니다. Try…Catch 구조체에서 벗어나기 바로 전에 Finally 블록으로 제어가 전달됩니다. Try 구조체 내부에서 예외가 발생하더라도 마찬가지입니다.

예외가 있더라도 반드시 실행해야 하는 코드를 실행하는 데에는 Finally 블록이 유용합니다. 제어는 Try...Catch 블록이 종료되는 방법에 관계없이 Finally 블록으로 전달됩니다.

Finally 블록의 코드는 Try 또는 Catch 블록에서 코드가 Return 문을 만나더라도 실행됩니다. 다음과 같은 경우에는 Try 또는 Catch 블록에서 해당 Finally 블록으로 제어가 전달되지 않습니다.

실행을 Finally 블록으로 명시적으로 전송할 수 없습니다. 또한 예외를 통하는 경우를 제외하고 Finally 블록에서 실행을 전송할 수 없습니다.

Try 문에 적어도 하나의 Catch 블록을 포함하지 않는 경우 Finally 블록을 포함해야 합니다.

특정 예외를 catch할 필요가 없는 경우, Try…Finally 블록처럼 동작하는 Using 문을 사용하면 블록 종료 방식에 관계없이 리소스를 삭제할 수 있습니다. 이는 처리되지 않은 예외의 경우에도 해당합니다. 자세한 내용은 Using 문(Visual Basic)을 참조하십시오.

예외 인수

Catch block exception 인수는 Exception 클래스의 인스턴스이거나 Exception 클래스에서 파생되는 클래스의 인스턴스입니다. Exception 클래스 인스턴스는 Try 블록에서 발생한 오류에 상응합니다.

Exception 개체의 속성을 통해 예외의 원인과 위치를 쉽게 확인할 수 있습니다. 예를 들어, 호출할 때 StackTrace 속성에 예외를 발생시킨 메서드가 나열되면 코드에서 오류 발생 위치를 쉽게 찾을 수 있습니다. Message는 예외를 설명하는 메시지를 반환합니다. HelpLink는 연결된 도움말 파일의 링크를 반환합니다. InnerException은 현재 예외를 발생시킨 Exception 개체를 반환하고 원본 Exception이 없는 경우는 Nothing을 반환합니다.

Try…Catch 문 사용 시 고려 사항

Try…Catch 문은 비정상적이거나 예상하지 않은 프로그램 이벤트의 발생을 알리기 위해서만 사용합니다. 이유는 다음과 같습니다.

  • 런타임에 예외를 catch하면 추가 오버헤드가 발생하며 사전 검사로 예외를 회피하는 경우에 비해 더 느려질 수 있습니다.

  • Catch 블록을 올바르게 처리하지 않으면 예외가 사용자에게 올바르게 보고되지 않을 수 있습니다.

  • 예외 처리를 사용하면 프로그램이 더 복잡해집니다.

발생 가능성이 높은 조건을 검사하기 위해 항상 Try…Catch 문을 사용할 필요는 없습니다. 다음 예제에서는 파일을 열기 전에 파일이 있는지 여부를 검사합니다. 이는 OpenText 메서드에서 throw한 예외를 catch할 필요성을 줄여 줍니다.

Private Sub TextFileExample(ByVal filePath As String)

    ' Verify that the file exists.
    If System.IO.File.Exists(filePath) = False Then
        Console.Write("File Not Found: " & filePath)
    Else
        ' Open the text file and display its contents.
        Dim sr As System.IO.StreamReader =
            System.IO.File.OpenText(filePath)

        Console.Write(sr.ReadToEnd)

        sr.Close()
    End If
End Sub

Catch 블록의 코드가 스레드 보안 또는 적절한 메시지를 통해 사용자에게 예외를 올바르게 보고하는지 확인하십시오. 그렇지 않으면 예외를 알지 못할 수 있습니다.

부분 신뢰 상황

네트워크 공유에 호스팅되는 응용 프로그램과 같은 부분 신뢰 상태에서 Try...Catch...Finally는 해당 호출이 포함된 메서드가 호출되기 전에 발생하는 보안 예외를 catch하지 않습니다. 다음 예제를 서버 공유에서 실행하면 "Sub System.Security.SecurityException: 요청하지 못했습니다."라는 오류가 발생합니다. 보안 예외에 대한 자세한 내용은 SecurityException 클래스를 참조하십시오.

Try
    Process.Start("https://www.microsoft.com")
Catch ex As Exception
    MsgBox("Can't load Web page" & vbCrLf & ex.Message)
End Try

이러한 부분 신뢰 상태에서는 Process.Start 문을 별도의 Sub에 두어야 합니다. 이렇게 하면 첫 번째 Sub를 호출하지 못하며 Process.Start를 포함하는 Sub가 시작되고 보안 예외가 생성되기 전에 Try...Catch에서 이를 catch할 수 있습니다.

예제

다음 예제에서는 Try...Catch...Finally 문의 구조를 보여 줍니다.

Public Sub TryExample()
    ' Declare variables.
    Dim x As Integer = 5
    Dim y As Integer = 0

    ' Set up structured error handling.
    Try
        ' Cause a "Divide by Zero" exception.
        x = x \ y

        ' This statement does not execute because program
        ' control passes to the Catch block when the
        ' exception occurs.
        MessageBox.Show("end of Try block")
    Catch ex As Exception
        ' Show the exception's message.
        MessageBox.Show(ex.Message)

        ' Show the stack trace, which is a list of methods
        ' that are currently executing.
        MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
    Finally
        ' This line executes whether or not the exception occurs.
        MessageBox.Show("in Finally block")
    End Try
End Sub

다음 예제에서는 CreateException 메서드가 NullReferenceException을 throw합니다. 예외를 발생시키는 코드가 Try 블록에 없습니다. 따라서 CreateException 메서드는 예외를 처리하지 않습니다. CreateException 메서드에 대한 호출이 Try 블록에 있으므로 RunSample 메서드는 예외를 처리하지 않습니다.

예제에는 몇 가지 예외 형식에 대한 Catch 문이 가장 구체적인 형식부터 가장 일반적인 형식의 순서로 포함되어 있습니다.

Public Sub RunSample()
    Try
        CreateException()
    Catch ex As System.IO.IOException
        ' Code that reacts to IOException.
    Catch ex As NullReferenceException
        MessageBox.Show("NullReferenceException: " & ex.Message)
        MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
    Catch ex As Exception
        ' Code that reacts to any other exception.
    End Try
End Sub

Private Sub CreateException()
    ' This code throws a NullReferenceException.
    Dim obj = Nothing
    Dim prop = obj.Name

    ' This code also throws a NullReferenceException.
    'Throw New NullReferenceException("Something happened.")
End Sub

다음 예제에서는 조건식에서 필터링하기 위해 Catch When을 사용하는 방법을 보여 줍니다. 조건식이 True인 경우 Catch 블록의 코드가 실행됩니다.

Private Sub WhenExample()
    Dim i As Integer = 5

    Try
        Throw New ArgumentException()
    Catch e As OverflowException When i = 5
        Console.WriteLine("First handler")
    Catch e As ArgumentException When i = 4
        Console.WriteLine("Second handler")
    Catch When i = 5
        Console.WriteLine("Third handler")
    End Try
End Sub
' Output: Third handler

다음 예제에는 Try 블록에 포함된 Try…Catch 문이 있습니다. 내부의 Catch 블록은 그 InnerException 속성이 원래 예외로 설정된 예외를 throw합니다. 외부 Catch 블록은 자체 예외와 내부 예외를 보고합니다.

Private Sub InnerExceptionExample()
    Try
        Try
            ' Set a reference to a StringBuilder.
            ' The exception below does not occur if the commented
            ' statement is used instead.
            Dim sb As System.Text.StringBuilder
            'Dim sb As New System.Text.StringBuilder

            ' Cause a NullReferenceException.
            sb.Append("text")
        Catch ex As Exception
            ' Throw a new exception that has the inner exception
            ' set to the original exception.
            Throw New ApplicationException("Something happened :(", ex)
        End Try
    Catch ex2 As Exception
        ' Show the exception.
        Console.WriteLine("Exception: " & ex2.Message)
        Console.WriteLine(ex2.StackTrace)

        ' Show the inner exception, if one is present.
        If ex2.InnerException IsNot Nothing Then
            Console.WriteLine("Inner Exception: " & ex2.InnerException.Message)
            Console.WriteLine(ex2.StackTrace)
        End If
    End Try
End Sub

참고 항목

참조

Err

Exit 문(Visual Basic)

On Error 문(Visual Basic)

Exception

Throw 문(Visual Basic)

개념

IntelliSense 코드 조각 사용에 관한 최선의 방법

예외 처리(작업 병렬 라이브러리)

기타 리소스

Visual Basic에서 구조적 예외 처리

변경 기록

날짜

변경 내용

이유

2011년 4월

재구성하고 비고에 추가한 다음 예제를 추가했습니다.

향상된 기능 관련 정보