Try...Catch...Finally, instruction (Visual Basic)

Fournit un moyen de gérer certaines ou toutes les erreurs possibles qui peuvent se produire dans un bloc de code donné, tout en continuant d’exécuter du code.

Syntax

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

Éléments

Terme Définition
tryStatements facultatif. Instruction (s) où une erreur peut se produire. Il peut s'agir d'une instruction composée.
Catch facultatif. CatchBlocs multiples autorisés. Si une exception se produit lors du traitement du Try bloc, chaque Catch instruction est examinée dans l’ordre textuel pour déterminer si elle gère l’exception, avec exception représentant l’exception qui a été levée.
exception facultatif. Tout nom de variable. La valeur initiale de l'argument exception est la valeur de l'erreur levée. Utilisé avec Catch pour spécifier l’erreur interceptée. En cas d’omission, l' Catch instruction intercepte toute exception.
type facultatif. Spécifie le type de filtre de classe. Si la valeur de exception est du type spécifié par type ou d’un type dérivé, l’identificateur est lié à l’objet d’exception.
When facultatif. Une Catch instruction avec une When clause intercepte les exceptions uniquement lorsque a la expression valeur True . Une When clause est appliquée uniquement après avoir vérifié le type de l’exception et expression peut faire référence à l’identificateur représentant l’exception.
expression facultatif. Doit être implicitement convertible en Boolean . Toute expression qui décrit un filtre générique. Généralement utilisé pour filtrer par numéro d’erreur. Utilisé avec When le mot clé pour spécifier les circonstances dans lesquelles l’erreur est interceptée.
catchStatements facultatif. Instruction (s) pour gérer les erreurs qui se produisent dans le Try bloc associé. Il peut s'agir d'une instruction composée.
Exit Try facultatif. Mot clé qui s’arrête hors de la Try...Catch...Finally structure. L’exécution reprend avec le code qui suit immédiatement l' End Try instruction. L' Finally instruction est toujours exécutée. Non autorisé dans les Finally blocs.
Finally facultatif. Un Finally bloc est toujours exécuté lorsque l’exécution quitte une partie de l' Try...Catch instruction.
finallyStatements facultatif. Instruction (s) qui sont exécutées une fois que toutes les autres opérations de traitement des erreurs se sont produites.
End Try Met fin à la Try...Catch...Finally structure.

Remarques

Si vous vous attendez à ce qu’une exception particulière se produise au cours d’une section de code particulière, placez le code dans un Try bloc et utilisez un Catch bloc pour conserver le contrôle et gérer l’exception, le cas échéant.

Une Try…Catch instruction se compose d’un Try bloc suivi d’une ou Catch de plusieurs clauses, qui spécifient des gestionnaires pour différentes exceptions. quand une exception est levée dans un Try bloc, Visual Basic recherche l' Catch instruction qui gère l’exception. si une Catch instruction correspondante est introuvable, Visual Basic examine la méthode qui a appelé la méthode actuelle, et ainsi de suite la pile des appels. si aucun Catch bloc n’est trouvé, Visual Basic affiche un message d’exception non gérée à l’utilisateur et arrête l’exécution du programme.

Vous pouvez utiliser plusieurs Catch instructions dans une Try…Catch instruction. Dans ce cas, l’ordre des Catch clauses est significatif, car ils sont examinés dans l’ordre. Interceptez les exceptions plus spécifiques avant les moins spécifiques.

Les Catch conditions d’instruction suivantes sont les moins spécifiques et interceptent toutes les exceptions qui dérivent de la Exception classe. En principe, vous devez utiliser l’une de ces variations comme dernier Catch bloc de la Try...Catch...Finally structure, après avoir intercepté toutes les exceptions spécifiques que vous attendez. Le workflow de contrôle ne peut jamais atteindre un Catch bloc qui suit l’une de ces variantes.

  • typeEst Exception , par exemple :Catch ex As Exception

  • L’instruction n’a pas exception de variable, par exemple : Catch

lorsqu’une Try…Catch…Finally instruction est imbriquée dans un autre Try bloc, Visual Basic examine d’abord chaque Catch instruction dans le bloc le plus profond Try . Si aucune Catch instruction correspondante n’est trouvée, la recherche se poursuit sur les Catch instructions du Try…Catch…Finally bloc externe.

Les variables locales d’un Try bloc ne sont pas disponibles dans un Catch bloc, car il s’agit de blocs distincts. Si vous souhaitez utiliser une variable dans plusieurs blocs, déclarez la variable en dehors de la Try...Catch...Finally structure.

Conseil

L' Try…Catch…Finally instruction est disponible sous la forme d’un extrait de code IntelliSense. Dans le gestionnaire des extraits de code, développez modèles de code-If, for each, try catch, Property, etc, puis la gestion des erreurs (exceptions). Pour plus d’informations, consultez Extraits de code.

Finally (bloc)

Si vous avez une ou plusieurs instructions qui doivent s’exécuter avant de quitter la Try structure, utilisez un Finally bloc. Le contrôle est passé au Finally bloc juste avant qu’il ne soit en dehors de la Try…Catch structure. Cela est vrai même si une exception se produit n’importe où dans la Try structure.

Un Finally bloc est utile pour exécuter tout code qui doit s’exécuter même en cas d’exception. Le contrôle est passé au Finally bloc, quelle que soit la façon dont le Try...Catch bloc s’arrête.

Le code d’un Finally bloc s’exécute même si votre code rencontre une Return instruction dans un Try bloc ou Catch . Le contrôle ne passe pas d' Try un Catch bloc ou au Finally bloc correspondant dans les cas suivants :

Il n’est pas possible de transférer explicitement l’exécution dans un Finally bloc. Le transfert de l’exécution en dehors d’un Finally bloc n’est pas valide, sauf par le biais d’une exception.

Si une Try instruction ne contient pas au moins un Catch bloc, elle doit contenir un Finally bloc.

Conseil

Si vous n’avez pas besoin d’intercepter des exceptions spécifiques, l' Using instruction se comporte comme un Try…Finally bloc et garantit la suppression des ressources, quelle que soit la façon dont vous quittez le bloc. Cela est vrai même avec une exception non gérée. Pour plus d’informations, consultez using, instruction.

Argument d’exception

L' Catch exception argument de bloc est une instance de la Exception classe ou une classe qui dérive de la Exception classe. L' Exception instance de classe correspond à l’erreur qui s’est produite dans le Try bloc.

Les propriétés de l' Exception objet permettent d’identifier la cause et l’emplacement d’une exception. Par exemple, la StackTrace propriété répertorie les méthodes appelées qui ont conduit à l’exception, ce qui vous permet de trouver où l’erreur s’est produite dans le code. Message retourne un message qui décrit l’exception. HelpLink retourne un lien vers un fichier d’aide associé. InnerException retourne l' Exception objet qui a provoqué l’exception actuelle, ou retourne Nothing s’il n’y a pas d’objet d’origine Exception .

Considérations à prendre en compte lors de l’utilisation d’un bloc try... Catch (instruction)

Utilisez une Try…Catch instruction uniquement pour signaler l’occurrence d’événements de programme inattendus ou imprévus. Les raisons sont les suivantes :

  • L’interception des exceptions au moment de l’exécution crée une surcharge supplémentaire et est susceptible d’être plus lente que la pré-vérification pour éviter les exceptions.

  • Si un Catch bloc n’est pas géré correctement, l’exception peut ne pas être signalée correctement aux utilisateurs.

  • La gestion des exceptions rend un programme plus complexe.

Vous n’avez pas toujours besoin Try…Catch d’une instruction pour vérifier une condition qui est susceptible de se produire. L’exemple suivant vérifie si un fichier existe avant d’essayer de l’ouvrir. Cela réduit le besoin d’intercepter une exception levée par la OpenText méthode.

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

Assurez-vous que le code des Catch blocs peut signaler correctement les exceptions aux utilisateurs, que ce soit via une journalisation thread-safe ou des messages appropriés. Sinon, les exceptions peuvent rester inconnues.

Méthodes Async

Si vous marquez une méthode avec le modificateur Async , vous pouvez utiliser l’opérateur await dans la méthode. Une instruction avec l' Await opérateur interrompt l’exécution de la méthode jusqu’à ce que la tâche attendue se termine. La tâche représente un travail en cours. Lorsque la tâche associée à l’opérateur se Await termine, l’exécution reprend dans la même méthode. pour plus d’informations, consultez Flow de contrôle dans les programmes Async.

Une tâche retournée par une méthode Async peut se terminer par un état d’erreur, ce qui indique qu’elle s’est terminée en raison d’une exception non gérée. Une tâche peut également se terminer par un état annulé, ce qui entraîne OperationCanceledException la levée d’une exception dans l’expression await. Pour intercepter l’un ou l’autre type d’exception, placez l' Await expression associée à la tâche dans un Try bloc, puis interceptez l’exception dans le Catch bloc. Un exemple est fourni plus loin dans cette rubrique.

Une tâche peut être dans un état d’erreur, car plusieurs exceptions étaient responsables de son erreur. Par exemple, la tâche peut être le résultat d'un appel à Task.WhenAll. Lorsque vous attendez une telle tâche, l’exception interceptée n’est qu’une des exceptions, et vous ne pouvez pas prédire l’exception qui sera interceptée. Un exemple est fourni plus loin dans cette rubrique.

Une Await expression ne peut pas se trouver à l’intérieur d’un Catch bloc ou d’un Finally bloc.

Iterators

Une fonction ou un Get accesseur d’itérateur effectue une itération personnalisée sur une collection. Un itérateur utilise une instruction yield pour retourner chaque élément de la collection un par un. Vous appelez une fonction d’itérateur à l’aide d’un pour chaque... Instruction suivante.

Une Yield instruction peut se trouver à l’intérieur d’un Try bloc. Un Try bloc qui contient une Yield instruction peut avoir des Catch blocs et peut avoir un Finally bloc. pour obtenir un exemple, consultez la section « blocs Try dans Visual Basic » d' itérateurs .

Une Yield instruction ne peut pas être à l’intérieur d’un Catch bloc ou d’un Finally bloc.

Si le For Each corps (en dehors de la fonction d’itérateur) lève une exception, un Catch bloc de la fonction d’itérateur n’est pas exécuté, mais un Finally bloc dans la fonction d’itérateur est exécuté. Un Catch bloc à l’intérieur d’une fonction d’itérateur intercepte uniquement les exceptions qui se produisent à l’intérieur de la fonction Iterator.

Situations de confiance partielle

Dans les situations de confiance partielle, telles qu’une application hébergée sur un partage réseau, Try...Catch...Finally n’intercepte pas les exceptions de sécurité qui se produisent avant l’appel de la méthode qui contient l’appel. L’exemple suivant, quand vous le placez sur un partage de serveur et que vous exécutez à partir de là, génère l’erreur « System. Security. SecurityException : échec de la demande ». Pour plus d’informations sur les exceptions de sécurité, consultez la SecurityException classe.

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

Dans une telle situation de confiance partielle, vous devez placer l' Process.Start instruction dans un distinct Sub . L’appel initial à l' Sub opération échoue. Cela permet Try...Catch à de l’intercepter avant Sub que le qui contient Process.Start ne démarre et que l’exception de sécurité soit produite.

Exemples

Structure de try... Catch... Suivie

L’exemple suivant illustre la structure de l' Try...Catch...Finally instruction.

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

Exception dans une méthode appelée à partir d’un bloc try

Dans l’exemple suivant, la CreateException méthode lève une exception NullReferenceException . Le code qui génère l’exception n’est pas dans un Try bloc. Par conséquent, la CreateException méthode ne gère pas l’exception. La RunSample méthode gère l’exception, car l’appel à la CreateException méthode se trouve dans un Try bloc.

L’exemple comprend Catch des instructions pour plusieurs types d’exceptions, classées du plus spécifique au plus général.

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

Instruction catch when

L’exemple suivant montre comment utiliser une Catch When instruction pour filtrer sur une expression conditionnelle. Si l’expression conditionnelle a la valeur True , le code du Catch bloc s’exécute.

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

Instructions Try imbriquées

L’exemple suivant contient une Try…Catch instruction contenue dans un Try bloc. Le Catch bloc interne lève une exception dont InnerException la propriété a la valeur de l’exception d’origine. Le Catch bloc externe signale sa propre exception et l’exception interne.

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

Gestion des exceptions pour les méthodes Async

L'exemple suivant illustre la gestion des exceptions pour les méthodes async. Pour intercepter une exception qui s’applique à une tâche asynchrone, l' Await expression se trouve dans un Try bloc de l’appelant et l’exception est interceptée dans le Catch bloc.

Supprimez les marques de commentaire de la ligne Throw New Exception dans l'exemple pour illustrer la gestion des exceptions. L’exception est interceptée dans le Catch bloc, la propriété de la tâche IsFaulted a la valeur et la True propriété de la tâche Exception.InnerException a la valeur de l’exception.

Supprimez les marques de commentaire de la ligne Throw New OperationCancelledException pour montrer ce qui se passe quand vous annulez un processus asynchrone. L’exception est interceptée dans le Catch bloc et la propriété de la tâche IsCanceled a la valeur True . Toutefois, dans certaines conditions qui ne s’appliquent pas à cet exemple, IsFaulted a la valeur True et IsCanceled a la valeur 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

Gestion de plusieurs exceptions dans les méthodes Async

L’exemple suivant illustre la gestion des exceptions quand plusieurs tâches peuvent entraîner plusieurs exceptions. Le Try bloc a l' Await expression de la tâche qui a été Task.WhenAll retournée. La tâche est terminée lorsque les trois tâches auxquelles Task.WhenAll est appliqué sont terminées.

Chacune de ces trois tâches provoque une exception. Le Catch bloc itère au sein des exceptions, qui se trouvent dans la Exception.InnerExceptions propriété de la tâche Task.WhenAll retournée.

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

Voir aussi