Visão Geral sobre a Manipulação Estruturada de Exceções para o Visual Basic

Visual Basic suporta a manipulação estruturada de exceções, que você pode usar para criar e manter programas com manipuladores de erro robustos e abrangentes. Manipulação estruturada de exceções é código desenvolvido para detectar e responder a erros durante a execução, combinando uma estrutura de controle (semelhante a Select Case ou While) com exceções, blocos de código protegidos, e filtros.

Usando a instrução Try...Catch...Finally, você pode proteger blocos de código que têm o potencial para gerar erros. Você pode aninhar manipuladores de exceção, e as variáveis declaradas em cada bloco terão escopo local.

link para vídeo Para uma demonstração de vídeo relacionada, consulte Fazer como i: Exceções sem tratamento de e-mails?.

A instrução Try...Catch...Finally

O código a seguir mostra a estrutura de uma instrução Try...Catch...Finally.

Try
    ' Starts a structured exception handler.
    ' Place executable statements that may generate 
    ' an exception in this block.
Catch '[optional filters]
    ' This code runs if the statements listed in 
    ' the Try block fail and the filter on the Catch statement is true.
'[Additional Catch blocks]
Finally
    ' This code always runs immediately before
    ' the Try statement exits.
End Try
' Ends a structured exception handler.

O bloco Try de um manipulador de exceções Try...Catch...Finally contém a seção de código a ser monitorado para exceções. Se ocorrer um erro durante a execução desta seção, o Visual Basic examina cada instrução Catch dentro do Try...Catch...Finally até encontrar uma com uma condição que corresponda a esse erro. Se uma for encontrada, o controle transfere para a primeira linha de código no bloco Catch. Se nenhuma declaração Catchcorrespondente for encontrada, a pesquisa passa para as instruções Catch do bloco Try...Catch...Finally externo que contém o bloco em que ocorreu a exceção. Este processo continua através da pilha inteira até um bloco Catch correspondente seja localizado no procedimento atual. Se nenhuma correspondência for encontrada, um erro é produzido.

O código na seção Finally sempre executa por último, imediatamente antes que o bloco de tratamento de erros perca escopo, independentemente de se ter executado o código nos blocos Catch. Coloque um código de limpeza, como os que fecham arquivos e liberam objetos, na seção Finally. Se você não precisa capturar exceções, mas precisa limpar recursos, considere usar a instrução Using em vez de uma seção Finally. Para obter mais informações, consulte Instrução Using (Visual Basic).

Erro de filtragem no bloco Catch

Blocos Catch permitem três opções de filtragem de erro específico. Em uma, os erros são filtrados com base na classe de exceção (nesse caso ClassLoadException), como mostrado no código a seguir.

Try
    ' "Try" block.
Catch e as ClassLoadException
    ' "Catch" block.
Finally
    ' "Finally" block.
End Try

Se ocorrer um erro ClassLoadException, o código dentro do bloco Catch especificado será executado.

Na segunda opção de filtragem de erro, a seção Catch pode filtrar em qualquer expressão condicional. Um uso comum desse tipo de filtro Catch é para testar números de erros específicos, como mostra o código a seguir.

Try
   ' "Try" block.
Catch When ErrNum = 5 'Type mismatch.
   ' "Catch" block.
Finally
   ' "Finally" block.
End Try

Quando o Visual Basic localiza o manipulador de erro correspondente, ele executa o código dentro desse manipulador, e então passa o controle para o bloco Finally.

ObservaçãoObservação

Quando tentava localizar um bloco Catch para manipular uma exceção, cada manipulador de bloco é avaliado até que uma correspondência seja encontrada. Como esses manipuladores podem ser chamadas a funções, é possível que haja efeitos colaterais inesperados; por exemplo, tal chamada pode alterar uma variável pública que é então usada no código de um bloco Catch diferente que acaba tratando a exceção.

Como uma terceira alternativa, você pode combinar as opções um e dois, usando ambas para tratamento de exceção. Suas instruções Catch devem se mover da mais específica para as menos específicas. Um bloco Catch por si só irá capturar todas as exceções derivadas do Exception, e portanto deve ser sempre o último bloco antes do Finally.

Ramificação de Blocos Try…Catch

É possível ramificar de um bloco Catch de volta para a instrução Try inicial ou para a instrução End Try,mas não é possível ramificar em um bloco Try…Catch delimitador. Isso é mostrado aqui:

Ramificação Try Catch

Exemplo de Manipulador de Exceção Estruturado

O exemplo a seguir mostra outro manipulador de erro simples que usa o Try...Catch...Finally instrução.

Option Strict On
Imports System.IO

Module Module1
    Private Const FileName As String = "TestFile.data"

    Public Sub Main()

        ' First, create a new data file and write some data to the file.
        ' 1. Create the new, empty data file.
        If File.Exists(FileName) Then
            File.Delete(FileName)
        End If
        Dim fs As New FileStream(FileName, FileMode.CreateNew)

        ' 2. Create a BinaryWriter object for the data.
        Dim writer As New BinaryWriter(fs)

        ' 3. Write some sample data to the file.
        For i = 0 To 10
            writer.Write(i)
        Next i
        writer.Close()
        fs.Close()

        ' Now read from the file you just made.
        ' 1. Create a BinaryReader object for the data stream.
        fs = New FileStream(FileName, FileMode.Open, FileAccess.Read)
        Dim reader As New BinaryReader(fs)

        ' 2. Read data from TestFile.data. The loop terminates with an
        ' EndOfStreamException when an attempt is made to read past
        ' the end of the stream.
        Try
            ' This loop terminates with an EndOfStreamException when it 
            ' reaches the end of the stream.
            While True
                Console.WriteLine(reader.ReadInt32())
            End While
            Console.WriteLine("The data was read with no error.")
        ' 3. Report the first error that is caught, if there is one.
        Catch eosExcep As EndOfStreamException
            ' This Catch block is executed when the reader attempts
            ' to read past the end of the stream.
            Console.WriteLine("End-of-stream exception occurred.")
        Catch IOExcep As System.IO.IOException
            ' For this Catch block, some other error occurred before
            ' the end of stream was reached. Print the standard
            ' exception message.
            Console.WriteLine(IOExcep.Message)
        Finally
            ' The Finally block is always executed.
            Console.WriteLine("Executing the Finally block.")
            reader.Close()
            fs.Close()
        End Try
    End Sub

End Module

O bloco Finally está sempre sendo executado, independentemente de quaisquer ações que ocorrem em blocos Catch anteriores. Não é possível usar Resume ou Resume Next em manipulação estruturada de exceções.

ObservaçãoObservação

No exemplo anterior, qualquer exceção diferente da classe IOException ou da classe EndOfStreamException é propagada de volta para o chamador não controlado.

Consulte também

Tarefas

A solução de problemas (Visual Basic) de manipulação de exceção

Referência

Instrução Try...Catch...Finally (Visual Basic)

BinaryReader

BinaryWriter

FileStream

Conceitos

Introdução ao (Visual Basic) de manipulação de exceção

Tipos de erros (Visual Basic)

Visão geral (Visual Basic) de manipulação de exceção não estruturada

Outros recursos

Tarefas (Visual Basic) de manipulação de exceção