Try...Catch...Finally, instruction (Visual Basic)
Permet de traiter une partie ou l'ensemble des erreurs possibles pouvant se produire dans un bloc de code donné, tout en continuant à exécuter le code.
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
Composants
Terme |
Définition |
tryStatements |
Optionnel.Instructions dans lesquelles une erreur peut se produire.Il peut s'agir d'une instruction composée. |
Catch |
Optionnel.Plusieurs blocs Catch sont autorisés.Si une exception se produit pendant le traitement du bloc Try, chaque instruction Catch est examinée dans l'ordre textuel afin de déterminer si elle gère cette exception, exception représentant l'exception qui a été levée. |
exception |
Optionnel.Tout nom de variable.La valeur initiale de l'argument exception est la valeur de l'erreur levée.Cet argument est utilisé avec Catch pour spécifier l'erreur interceptée.S'il est omis, l'instruction Catch intercepte n'importe quelle exception. |
type |
Optionnel.Spécifie le type d'un filtre de classe.Si la valeur de l'argument exception est l'un des types spécifiés par type ou un type dérivé, l'identificateur est lié à l'objet exception. |
When |
Optionnel.Une instruction Catch avec une clause When intercepte les exceptions uniquement lorsque expression a la valeur True.Une clause When n'est appliquée qu'après le contrôle du type de l'exception, et expression peut faire référence à l'identificateur qui représente l'exception. |
expression |
Optionnel.Doit pouvoir être converti implicitement en type Boolean.Toute expression qui décrit un filtre générique.Généralement utilisé pour effectuer un filtre selon le numéro de l'erreur.Cet argument est utilisé avec le mot clé When pour spécifier des circonstances permettant d'intercepter l'erreur. |
catchStatements |
Optionnel.Instruction(s) permettant de gérer des erreurs se produisant dans le bloc Try associé.Il peut s'agir d'une instruction composée. |
Exit Try |
Optionnel.Mot clé qui décompose la structure Try...Catch...Finally.L'exécution reprend par le code qui suit immédiatement l'instruction End Try.L'instruction Finally sera toujours exécutée.Non autorisé dans les blocs Finally. |
Finally |
Optionnel.Un bloc Finally est toujours exécuté quand l'exécution quitte une partie quelconque de l'instruction Try...Catch. |
finallyStatements |
Optionnel.Instructions qui sont exécutées à la fin du traitement de toutes les autres erreurs. |
End Try |
Met fin à la structure Try...Catch...Finally. |
Notes
Si vous vous attendez à ce qu'une exception particulière se produise pendant une section particulière de code, mettez le code dans un bloc Try et utilisez un bloc Catch pour conserver le contrôle et gérer l'exception si elle se produit.
Une instruction Try…Catch est un bloc Try suivi par une ou plusieurs clauses Catch, qui spécifient les gestionnaires de diverses exceptions.Lorsqu'une exception est levée dans un bloc Try, Visual Basic recherche l'instruction Catch qui gère l'exception.Si une instruction Catch correspondante n'est pas trouvée, Visual Basic examine la méthode qui a appelé la méthode actuelle, et ainsi de suite dans la pile des appels.Si aucun bloc Catch n'est trouvé, Visual Basic affiche un message d'exception non gérée destiné à l'utilisateur et arrête l'exécution du programme.
Vous pouvez utiliser plusieurs instructions Catch dans une instruction Try…Catch.Si vous faites cela, l'ordre des clauses Catch est important car celles-ci sont examinées dans l'ordre.Interceptez les exceptions les plus spécifiques avant celles qui le sont le moins.
Les conditions de l'instruction Catch suivantes sont les moins spécifiques et intercepteront toutes les exceptions dérivant de la classe Exception.Vous devez normalement utiliser l'une de ces variations comme dernier bloc Catch dans la structure Try...Catch...Finally, après avoir intercepté toutes les exceptions spécifiques que vous prévoyez.Le flux de contrôle ne peut jamais atteindre un bloc Catch qui suit l'une de ces variations.
type a la valeur Exception, par exemple : Catch ex As Exception
L'instruction n'a aucune variable exception, par exemple : Catch
Lorsqu'une instruction Try…Catch…Finally est imbriquée dans un autre bloc Try, Visual Basic examine d'abord chaque instruction Catch dans le bloc Try le plus profond.Si aucune instruction Catch correspondante n'est trouvée, la recherche se poursuit aux instructions Catch du bloc externe Try…Catch…Finally.
Les variables locales d'un bloc Try ne sont pas disponibles dans un bloc Catch, car ce sont des blocs séparés.Si vous voulez utiliser une variable dans plusieurs blocs, déclarez la variable à l'extérieur de la structure Try...Catch...Finally.
Conseil |
---|
L'instruction Try…Catch…Finally est disponible sous forme d'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 Gestion des erreurs (Exceptions).Pour plus d'informations, consultez Extraits de code. |
Bloc Finally
Si une ou plusieurs instructions doivent être exécutées avant que vous ne sortiez de la structure Try, utilisez un bloc Finally.Le contrôle passe au bloc Finally juste avant de sortir de la structure Try…Catch.Cela est vrai même si une exception se produit où que ce soit dans la structure Try.
Un bloc Finally est utile pour l'exécution de tout code qui doit s'exécuter même en cas d'exception.Le contrôle est transmis au bloc Finally quelle que soit la méthode de sortie du bloc Try...Catch.
Le code dans un bloc Finally s'exécute même si votre code rencontre une instruction Return ou Try dans un bloc Catch ou .Le contrôle ne passe pas d'un bloc Try ou Catch au bloc Finally correspondant dans les cas suivants :
Une End, instruction est rencontrée dans le bloc Try ou Catch.
Une StackOverflowException est levée dans le bloc Try ou Catch.
Il n'est pas valide pour transférer explicitement l'exécution dans un bloc d' Finally .Transférer l'exécution en dehors d'un bloc d' Finally est pas valide, sauf dans une exception.
Si une instruction Try ne contient pas au moins un bloc Catch, elle doit contenir un bloc Finally.
Conseil |
---|
Si vous n'avez pas besoin d'intercepter des exceptions spécifiques, l'instruction Using se comporte comme un bloc Try…Finally et garantit l'élimination des ressources, quelle que soit la manière dont vous quittez le bloc.Cela est vrai même avec une exception non gérée.Pour plus d'informations, consultez Using, instruction (Visual Basic). |
Argument d'exception
L'argument exception du bloc Catch est une instance de la classe Exception ou une classe qui dérive de la classe Exception.L'instance de la classe Exception correspond à l'erreur qui s'est produite dans le bloc Try.
Les propriétés de l'objet Exception permettent d'identifier la cause et l'emplacement d'une exception.Par exemple, la propriété StackTrace répertorie les méthodes appelées qui ont abouti à l'exception, ce qui vous permet de rechercher l'emplacement de l'erreur dans le code.Message renvoie un message qui décrit l'exception.HelpLink renvoie un lien vers un fichier d'aide associé.InnerException renvoie l'objet Exception qui a provoqué l'exception en cours, ou renvoie Nothing s'il n'existe aucune Exception originale.
Considérations sur l'utilisation d'une instruction Try…Catch
Utilisez une instruction Try…Catch uniquement pour signaler que des événements inhabituels ou imprévus se sont produits.Cette opération se produit pour les raisons suivantes :
L'interception d'exceptions lors de l'exécution crée une charge mémoire supplémentaire et est susceptible d'être plus lente que la pré-vérification pour éviter les exceptions.
Si un bloc Catch n'est pas correctement traité, l'exception ne sera peut-être pas rapportée de façon correcte aux utilisateurs.
La gestion des exceptions rend plus complexe un programme.
Une instruction Try…Catch n'est pas toujours nécessaire pour rechercher une condition qui risque probablement de se produire.L'exemple suivant vérifie si un fichier existe avant de tenter de l'ouvrir.Cela réduit la nécessité d'intercepter une exception levée par la méthode OpenText.
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
Veiller à ce que le code dans les blocs Catch puisse signaler correctement les exceptions aux utilisateurs, que ce soit par la journalisation thread-safe ou des messages appropriés.Sinon, les exceptions pourraient rester inconnues.
Méthodes Async
Si vous marquez une méthode avec le modificateur d' Async , vous pouvez utiliser l'opérateur d' attendez dans la méthode.Une instruction avec l'opérateur d' Await interrompt l'exécution de la méthode jusqu'à ce que la tâche se termine attendue.La tâche représente le travail actif.Lorsque la tâche associée à l'opérateur d' Await terminée, l'exécution se poursuit dans la même méthode.Pour plus d'informations, consultez Flux de contrôle dans les programmes Async (C# et Visual Basic).
Une tâche retournée par une méthode Async peut se terminer dans un état censuré, indiquant qu'elle est terminée en raison d'une exception non gérée.Une tâche peut également se terminer dans un état canceled, ce qui entraîne OperationCanceledException est levée en dehors de l'expression d'attente.Pour intercepter l'un ou l'autre type d'exception, définissez l'expression d' Await associée à la tâche dans un bloc d' Try , et intercepter l'exception dans le bloc d' Catch .Un exemple est plus loin dans cette rubrique.
Une tâche peut être dans un état censuré car plusieurs exceptions ont été chargées de sa dislocation.Par exemple, la tâche peut être le résultat d'un appel à Task.WhenAll.Lorsque vous attendez une telle tâche, l'exception est interceptée une seule des exceptions, et vous ne pouvez pas prévoir une exception est interceptée.Un exemple est plus loin dans cette rubrique.
Une expression d' Await ne peut pas être dans un bloc d' Catch ou de bloc d' Finally .
Itérateurs
Une fonction d'itérateur ou un utilisateur d' Get effectue une itération au sein d'une collection.Un itérateur utilise une instruction de rendement pour retourner chaque élément de la collection un par un.Vous appelez une fonction d'itérateur à l'aide de For Each...Next, instruction (Visual Basic).
Une instruction d' Yield peut se trouver dans un bloc d' Try .Un bloc d' Try qui contient une instruction d' Yield peut avoir des blocs d' Catch , et peut avoir un bloc d' Finally .Consultez des « bloc try la section dans Visual Basic » d' Itérateurs (C# et Visual Basic) pour un exemple.
Une instruction d' Yield ne peut pas être dans un bloc d' Catch ou d'un bloc d' Finally .
Si le corps d' For Each (en dehors de la fonction d'itérateur) lève une exception, un bloc d' Catch dans la fonction d'itérateur n'est pas exécuté, mais un bloc d' Finally dans la fonction d'itérateur est exécuté.Un bloc d' Catch à l'intérieur d'une fonction d'itérateur intercepte uniquement les exceptions qui se produisent à l'intérieur de la fonction d'itérateur.
Situations d'un niveau de confiance partiel
Dans les situations d'un niveau de confiance partiel, comme 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 que la méthode qui contient l'appel ne soit appelée.L'exemple suivant, s'il est placé sur un partage réseau et exécuté à cet endroit, produit l'erreur : "System.Security.SecurityException: Échec de la demande". Pour plus d'informations sur les exceptions de sécurité, consultez la classe SecurityException.
Try
Process.Start("https://www.microsoft.com")
Catch ex As Exception
MsgBox("Can't load Web page" & vbCrLf & ex.Message)
End Try
Dans la situation d'un niveau de confiance partiel, vous devez placer l'instruction Process.Start dans un Sub séparé.L'appel initial au Sub échoue.Cela permet à Try...Catch de l'intercepter avant le démarrage du Sub qui contient Process.Start et l'exécution de l'exception de sécurité.
Exemple
L'exemple ci-dessous illustre la structure de l'instruction 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
Dans l'exemple suivant, la méthode CreateException lève une NullReferenceException.Le code qui génère l'exception n'est pas dans un bloc Try.Par conséquent, la méthode CreateException ne gère pas l'exception.La méthode RunSample gère l'exception car l'appel à la méthode CreateException est dans un bloc Try.
L'exemple inclut des instructions Catch pour plusieurs types d'exceptions, classées de la plus spécifique à la plus générale.
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
L'exemple suivant montre comment utiliser une instruction Catch When pour filtrer sur une expression conditionnelle.Si l'expression conditionnelle a la valeur True, le code dans le bloc Catch 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
L'exemple suivant a une instruction Try…Catch contenue dans un bloc Try.Le bloc interne Catch lève une exception dont la propriété InnerException est définie sur l'exception d'origine.Le bloc Catch 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
L'exemple suivant illustre la gestion des exceptions pour les méthodes async.Pour intercepter une exception qui s'applique à une tâche async, l'expression d' Await est dans un bloc d' Try de l'appelant, et l'exception est interceptée dans le bloc d' Catch .
Supprimez les marques de commentaire de la ligne de Throw New Exception l'exemple pour illustrer la gestion des exceptions.L'exception est interceptée dans le bloc d' Catch , la propriété d' IsFaulted de la tâche a True, et la propriété d' Exception.InnerException de la tâche a pour valeur l'exception.
Supprimez les marques de commentaire de la ligne de Throw New OperationCancelledException pour illustrer ce qui se produit lorsque vous supprimez un processus asynchrone.L'exception est interceptée dans le bloc d' Catch , et la propriété d' IsCanceled de la tâche a 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
L'exemple suivant illustre la gestion des exceptions lorsque plusieurs tâches peuvent entraîner de plusieurs exceptions.Le bloc d' Try a l'expression d' Await pour la tâche à Task.WhenAll est retournée.La tâche est terminée lorsque les trois tâches auxquelles Task.WhenAll est appliqué sont terminées.
Les trois causes de tâches une exception.Le bloc d' Catch itère au sein de les exceptions, qui se trouvent dans la propriété d' Exception.InnerExceptions de la tâche à Task.WhenAll est 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
Référence
Exit, instruction (Visual Basic)
On Error, instruction (Visual Basic)
Throw, instruction (Visual Basic)
Concepts
Meilleures pratiques pour l'utilisation des extraits de code