Try...Catch...Finally Instrução (Visual Basic)
Fornece uma maneira de lidar com alguns ou todos os erros possíveis que podem ocorrer em um determinado bloco de código, enquanto ainda executa o código.
Sintaxe
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
Partes
Termo | Definição |
---|---|
tryStatements |
Opcional. Instrução(ões) onde um erro pode ocorrer. Pode ser uma instrução composta. |
Catch |
Opcional. Vários Catch blocos permitidos. Se ocorrer uma exceção durante o processamento do Try bloco, cada Catch instrução será examinada em ordem textual para determinar se ela manipula a exceção, representando exception a exceção que foi lançada. |
exception |
Opcional. Qualquer nome de variável. O valor inicial de exception é o valor do erro lançado. Usado com Catch para especificar o erro detetado. Se omitida, a Catch declaração captura qualquer exceção. |
type |
Opcional. Especifica o tipo de filtro de classe. Se o valor de é do tipo especificado por exception ou de um tipo derivado, o identificador torna-se vinculado ao objeto de type exceção. |
When |
Opcional. Uma Catch declaração com uma When cláusula captura exceções somente quando expression avaliada como True . Uma When cláusula só é aplicada depois de verificado o tipo de exceção e expression pode referir-se ao identificador que representa a exceção. |
expression |
Opcional. Deve ser implicitamente convertível em Boolean . Qualquer expressão que descreva um filtro genérico. Normalmente usado para filtrar por número de erro. Usado com When palavra-chave para especificar as circunstâncias em que o erro é detetado. |
catchStatements |
Opcional. Instrução(ões) para lidar com erros que ocorrem no bloco associado Try . Pode ser uma instrução composta. |
Exit Try |
Opcional. Palavra-chave que rompe a Try...Catch...Finally estrutura. A execução é retomada com o código imediatamente após a End Try instrução. A Finally instrução ainda será executada. Não permitido em Finally blocos. |
Finally |
Opcional. Um Finally bloco é sempre executado quando a execução deixa qualquer parte da Try...Catch instrução. |
finallyStatements |
Opcional. Instrução(ões) que são executadas após o processamento de todos os outros erros terem ocorrido. |
End Try |
Encerra a Try...Catch...Finally estrutura. |
Observações
Se você espera que uma exceção específica possa ocorrer durante uma seção específica do código, coloque o código em um Try
bloco e use um Catch
bloco para manter o controle e manipular a exceção se ela ocorrer.
Uma Try…Catch
instrução consiste em um Try
bloco seguido por uma ou mais Catch
cláusulas, que especificam manipuladores para várias exceções. Quando uma exceção é lançada em um Try
bloco, o Visual Basic procura a Catch
instrução que manipula a exceção. Se uma instrução correspondente Catch
não for encontrada, o Visual Basic examinará o método que chamou o método atual e assim por diante na pilha de chamadas. Se nenhum Catch
bloco for encontrado, o Visual Basic exibirá uma mensagem de exceção sem tratamento para o usuário e interromperá a execução do programa.
Você pode usar mais de uma Catch
instrução em uma Try…Catch
instrução. Se o fizer, a ordem das cláusulas é significativa porque são examinadas Catch
por ordem.
Catch as exceções mais específicas antes das menos específicas.
As condições da instrução Catch
a seguir são as menos específicas e capturarão todas as exceções derivadas da classe Exception. Normalmente, você deve usar uma dessas variações como o último Catch
bloco na Try...Catch...Finally
estrutura, depois de capturar todas as exceções específicas que você espera. O fluxo de controle nunca pode atingir um bloco que siga qualquer uma Catch
dessas variações.
O
type
éException
, por exemplo:Catch ex As Exception
A instrução não
exception
tem variável, por exemplo:Catch
Quando uma Try…Catch…Finally
instrução é aninhada em outro Try
bloco, o Visual Basic primeiro examina cada Catch
instrução no bloco mais Try
interno. Se nenhuma instrução correspondente Catch
for encontrada, a pesquisa prosseguirá para as Catch
instruções do bloco externo Try…Catch…Finally
.
As variáveis locais de um Try
bloco não estão disponíveis em um Catch
bloco porque são blocos separados. Se você quiser usar uma variável em mais de um bloco, declare a variável fora da Try...Catch...Finally
estrutura.
Gorjeta
A Try…Catch…Finally
instrução está disponível como um trecho de código do IntelliSense. No Gerenciador de trechos de código, expanda Padrões de código - Se, para cada um, TryCatch, Propriedade, etc e, em seguida, Tratamento de erros (exceções). Para obter mais informações, consulte Trechos de código.
bloco Finally
Se você tiver uma ou mais instruções que devem ser executadas antes de sair da Try
estrutura, use um Finally
bloco. O controle passa para o Finally
bloco pouco antes de ele sair da Try…Catch
estrutura. Isso é verdade mesmo se uma exceção ocorrer em qualquer lugar dentro da Try
estrutura.
Um Finally
bloco é útil para executar qualquer código que deva ser executado, mesmo que haja uma exceção. O controle é passado para o Finally
bloco independentemente de como o Try...Catch
bloco sai.
O código em um Finally
bloco é executado mesmo se o código encontrar uma Return
instrução em um Try
ou Catch
bloco. O controlo não passa de um Try
ou Catch
bloco para o bloco correspondente Finally
nos seguintes casos:
Uma instrução End é encontrada no
Try
bloco ouCatch
.A StackOverflowException é jogado no
Try
ouCatch
bloco.
Não é válido transferir explicitamente a execução para um Finally
bloco. A transferência da execução para fora de um Finally
bloco não é válida, exceto através de uma exceção.
Se uma Try
instrução não contiver pelo menos um Catch
bloco, ela deve conter um Finally
bloco.
Gorjeta
Se não for necessário capturar exceções específicas, a instrução Using
comporta-se como um bloco Try…Finally
e garante o descarte dos recursos, independentemente de como sair do bloco. Isso é verdade mesmo com uma exceção não tratada. Para obter mais informações, consulte Usando instrução.
Argumento de exceção
O Catch
argumento block exception
é uma instância da Exception classe ou uma classe que deriva da Exception
classe. A Exception
instância de classe corresponde ao erro que ocorreu no Try
bloco .
As propriedades do Exception
objeto ajudam a identificar a causa e o local de uma exceção. Por exemplo, a StackTrace propriedade lista os métodos chamados que levaram à exceção, ajudando você a encontrar onde o erro ocorreu no código.
Message Retorna uma mensagem que descreve a exceção.
HelpLink retorna um link para um arquivo de Ajuda associado.
InnerException retorna o Exception
objeto que causou a exceção atual ou retorna Nothing
se não houver nenhum original Exception
.
Considerações ao usar uma Try…Catch
instrução
Use uma Try…Catch
instrução apenas para sinalizar a ocorrência de eventos incomuns ou imprevistos do programa. As razões para isso incluem o seguinte:
Capturar exceções em tempo de execução cria sobrecarga adicional e provavelmente será mais lento do que a pré-verificação para evitar exceções.
Se um
Catch
bloco não for tratado corretamente, a exceção pode não ser relatada corretamente aos usuários.O tratamento de exceções torna um programa mais complexo.
Nem sempre é necessária uma Try…Catch
declaração para verificar a existência de uma condição suscetível de ocorrer. O exemplo a seguir verifica se um arquivo existe antes de tentar abri-lo. Isso reduz a necessidade de capturar uma exceção lançada pelo OpenText método.
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
Certifique-se de que o código em Catch
blocos possa relatar adequadamente as exceções aos usuários, seja por meio de registro seguro de threads ou mensagens apropriadas. Caso contrário, as exceções podem permanecer desconhecidas.
Métodos assíncronos
Se você marcar um método com o modificador Async , poderá usar o operador Await no método. Uma instrução com o operador suspende Await
a execução do método até que a tarefa aguardada seja concluída. A tarefa representa um trabalho contínuo. Quando a tarefa associada ao Await
operador é concluída, a execução é retomada no mesmo método. Para obter mais informações, consulte Fluxo de controle em programas assíncronos.
Uma tarefa retornada por um método Assíncrono pode terminar em um estado com falha, indicando que foi concluída devido a uma exceção não tratada. Uma tarefa também pode terminar em um estado cancelado, o que resulta em um OperationCanceledException
ser expulso da expressão aguardar. Para capturar qualquer tipo de exceção, coloque a expressão Await
associada à tarefa em um bloco Try
e capture a exceção no bloco Catch
. Um exemplo é fornecido mais adiante neste tópico.
Uma tarefa pode estar em um estado de falha porque várias exceções foram responsáveis por sua falha. Por exemplo, a tarefa pode ser o resultado de uma chamada para Task.WhenAll. Quando você aguarda tal tarefa, a exceção capturada é apenas uma das exceções, e você não pode prever qual exceção será capturada. Um exemplo é fornecido mais adiante neste tópico.
Uma Await
expressão não pode estar dentro de um Catch
bloco ou Finally
bloco.
Iteradores
Uma função iteradora ou Get
acessador executa uma iteração personalizada sobre uma coleção. Um iterador usa uma instrução Yield para retornar cada elemento da coleção, um de cada vez. Você chama uma função de iterador usando um For Each... Próxima declaração.
Uma Yield
instrução pode estar dentro de um Try
bloco. Um Try
bloco que contém uma Yield
instrução pode ter Catch
blocos e pode ter um Finally
bloco. Para obter um exemplo, consulte Try Blocos.
Uma Yield
instrução não pode estar dentro de um Catch
bloco ou de um Finally
bloco.
Se o For Each
corpo (fora da função iterador) lançar uma exceção, um Catch
bloco na função iterador não será executado, mas um Finally
bloco na função iterador será executado. Um Catch
bloco dentro de uma função iteradora captura apenas exceções que ocorrem dentro da função iterador.
Situações de confiança parcial
Em situações de confiança parcial, como um aplicativo hospedado em um compartilhamento de rede, o Try...Catch...Finally
não captura exceções de segurança que ocorrem antes que o método que contém a chamada seja invocado. O exemplo a seguir, quando você o coloca em um compartilhamento de servidor e executa a partir daí, produz o erro "System.Security.SecurityException: Falha na solicitação". Para obter mais informações sobre exceções de segurança, consulte a SecurityException classe.
Try
Process.Start("http://www.microsoft.com")
Catch ex As Exception
Console.WriteLine("Can't load Web page" & vbCrLf & ex.Message)
End Try
Em tal situação de confiança parcial, você tem que colocar a Process.Start
declaração em separado Sub
. A chamada inicial para o Sub
irá falhar. Isso permite que Try...Catch
o intercepte antes que Sub
, que contém Process.Start
, seja iniciado e a exceção de segurança seja produzida.
Exemplos
A estrutura do Try...Catch...Finally
O exemplo a seguir ilustra a estrutura da Try...Catch...Finally
instrução.
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.
Console.WriteLine("end of Try block")
Catch ex As Exception
' Show the exception's message.
Console.WriteLine(ex.Message)
' Show the stack trace, which is a list of methods
' that are currently executing.
Console.WriteLine("Stack Trace: " & vbCrLf & ex.StackTrace)
Finally
' This line executes whether or not the exception occurs.
Console.WriteLine("in Finally block")
End Try
End Sub
Exceção em um método chamado de um Try
bloco
No exemplo a seguir, o CreateException
método lança um NullReferenceException
arquivo . O código que gera a exceção não está em um Try
bloco. Portanto, o CreateException
método não manipula a exceção. O RunSample
método manipula a exceção porque a chamada para o CreateException
método está em um Try
bloco.
O exemplo inclui Catch
instruções para vários tipos de exceções, ordenadas do mais específico para o mais geral.
Public Sub RunSample()
Try
CreateException()
Catch ex As System.IO.IOException
' Code that reacts to IOException.
Catch ex As NullReferenceException
Console.WriteLine("NullReferenceException: " & ex.Message)
Console.WriteLine("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
A Catch instrução When
O exemplo a seguir mostra como usar uma Catch When
instrução para filtrar uma expressão condicional. Se a expressão condicional for avaliada como True
, o Catch
código no bloco será executado.
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
Instruções aninhadas Try
O exemplo a seguir tem uma Try…Catch
instrução contida em um Try
bloco . O bloco interno Catch
lança uma exceção que tem sua InnerException
propriedade definida como a exceção original. O bloco externo Catch
relata sua própria exceção e a exceção interna.
Private Sub InnerExceptionExample()
Try
Try
' Set a reference to a StringBuilder.
' The exception below does not occur if the commented
' out 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
Tratamento de exceções para métodos assíncronos
O exemplo a seguir ilustra o tratamento de exceções para métodos assíncronos. Para capturar uma exceção que se aplica a uma tarefa assíncrona, a expressão Await
está em um bloco Try
do chamador e a exceção é capturada no bloco Catch
.
Descomente a linha no exemplo para demonstrar o Throw New Exception
tratamento de exceções. A exceção é capturada Catch
no bloco , a propriedade da IsFaulted
tarefa é definida como True
, e a propriedade da Exception.InnerException
tarefa é definida como a exceção.
Descomente a linha para demonstrar o que acontece quando você cancela um processo assíncrono Throw New OperationCancelledException
. A exceção é capturada Catch
no bloco e a propriedade da IsCanceled
tarefa é definida como True
. No entanto, sob algumas condições que não se aplicam a este exemplo, IsFaulted
está definido como True
e IsCanceled
está definido como False
.
Public Async Function DoSomethingAsync() As Task
Dim theTask As Task(Of String) = DelayAsync()
Try
Dim result As String = Await theTask
Debug.WriteLine("Result: " & result)
Catch ex As Exception
Debug.WriteLine("Exception Message: " & ex.Message)
End Try
Debug.WriteLine("Task IsCanceled: " & theTask.IsCanceled)
Debug.WriteLine("Task IsFaulted: " & theTask.IsFaulted)
If theTask.Exception IsNot Nothing Then
Debug.WriteLine("Task Exception Message: " &
theTask.Exception.Message)
Debug.WriteLine("Task Inner Exception Message: " &
theTask.Exception.InnerException.Message)
End If
End Function
Private Async Function DelayAsync() As Task(Of String)
Await Task.Delay(100)
' Uncomment each of the following lines to
' demonstrate exception handling.
'Throw New OperationCanceledException("canceled")
'Throw New Exception("Something happened.")
Return "Done"
End Function
' Output when no exception is thrown in the awaited method:
' Result: Done
' Task IsCanceled: False
' Task IsFaulted: False
' Output when an Exception is thrown in the awaited method:
' Exception Message: Something happened.
' Task IsCanceled: False
' Task IsFaulted: True
' Task Exception Message: One or more errors occurred.
' Task Inner Exception Message: Something happened.
' Output when an OperationCanceledException or TaskCanceledException
' is thrown in the awaited method:
' Exception Message: canceled
' Task IsCanceled: True
' Task IsFaulted: False
Tratamento de várias exceções em métodos assíncronos
O exemplo a seguir ilustra o tratamento de exceções em que várias tarefas podem resultar em várias exceções. O Try
bloco tem a Await
expressão para a tarefa que Task.WhenAll retornou. A tarefa é concluída quando as três tarefas às quais Task.WhenAll é aplicado estão concluídas.
Cada uma das três tarefas causa uma exceção. O Catch
bloco itera através das exceções, que são encontradas na Exception.InnerExceptions
propriedade da tarefa que Task.WhenAll
retornou.
Public Async Function DoMultipleAsync() As Task
Dim theTask1 As Task = ExcAsync(info:="First Task")
Dim theTask2 As Task = ExcAsync(info:="Second Task")
Dim theTask3 As Task = ExcAsync(info:="Third Task")
Dim allTasks As Task = Task.WhenAll(theTask1, theTask2, theTask3)
Try
Await allTasks
Catch ex As Exception
Debug.WriteLine("Exception: " & ex.Message)
Debug.WriteLine("Task IsFaulted: " & allTasks.IsFaulted)
For Each inEx In allTasks.Exception.InnerExceptions
Debug.WriteLine("Task Inner Exception: " + inEx.Message)
Next
End Try
End Function
Private Async Function ExcAsync(info As String) As Task
Await Task.Delay(100)
Throw New Exception("Error-" & info)
End Function
' Output:
' Exception: Error-First Task
' Task IsFaulted: True
' Task Inner Exception: Error-First Task
' Task Inner Exception: Error-Second Task
' Task Inner Exception: Error-Third Task