Partager via


Envoi et réception des erreurs

Les erreurs SOAP acheminent des informations de condition d'erreur d'un service à un client et, dans le cas duplex, d'un client à un service d'une manière interopérable. En général un service définit le contenu des erreurs personnalisées et spécifie quelles opérations peuvent les retourner. (Pour plus d'informations, consultez Définition et spécification des erreurs.) Cette rubrique explique comment un service ou un client duplex peut envoyer ces erreurs lorsque la condition d'erreur correspondante s'est produite et comment un client ou une application de service gère ces erreurs. Pour une vue d'ensemble du traitement des erreurs dans les applications Windows Communication Foundation (WCF), consultez Spécification et gestion des erreurs dans les contrats et les services.

Envoi d'erreurs SOAP

Les erreurs SOAP déclarées sont celles dans lesquelles une opération contient un System.ServiceModel.FaultContractAttribute qui spécifie un type d'erreur SOAP personnalisé. Les erreurs SOAP non déclarées sont celles qui ne sont pas spécifiées dans le contrat d'une opération.

Envoi d'erreurs déclarées

Pour envoyer une erreur SOAP déclarée, détectez la condition d'erreur pour laquelle l'erreur SOAP est appropriée et levez une nouvelle System.ServiceModel.FaultException où le paramètre de type est un nouvel objet du type spécifié dans le FaultContractAttribute pour cette opération. L'exemple de code suivant illustre l'utilisation de FaultContractAttribute pour spécifier que l'opération SampleMethod peut retourner une erreur SOAP avec le type de détail GreetingFault.

<OperationContract, FaultContractAttribute(GetType(GreetingFault), Action:="https://www.contoso.com/GreetingFault", ProtectionLevel:=ProtectionLevel.EncryptAndSign)> _
Function SampleMethod(ByVal msg As String) As String

Pour acheminer les informations sur l'erreur GreetingFault au client, interceptez la condition d'erreur appropriée et levez une nouvelle System.ServiceModel.FaultException de type GreetingFault avec un nouvel objet GreetingFault comme argument, comme dans l'exemple de code suivant. Si le client est une application cliente WCF, il subit cette erreur en tant qu'exception managée où le type est System.ServiceModel.FaultException de type GreetingFault.

  Throw New FaultException(Of GreetingFault)(New GreetingFault("A Greeting error occurred. You said: " & msg))
End If

Envoi d'erreurs non déclarées

L'envoi d'erreurs non déclarées peut être très utile pour diagnostiquer et déboguer rapidement des problèmes dans les applications WCF, mais son utilité en tant qu'outil de débogage est limitée. Plus généralement, lors du débogage il est recommandé d'utiliser la propriété System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults. Lorsque vous définissez cette valeur à « true », les clients rencontrent des erreurs telles que des exceptions FaultException de type ExceptionDetail.

ms732013.Important(fr-fr,VS.100).gif Remarque :
Étant donné que les exceptions managées peuvent exposer des informations d'application internes, affecter la valeur true à System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults ou System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults peut autoriser des clients WCF à obtenir des informations sur des exceptions d'opération de service internes, y compris des informations personnellement identifiables ou autres informations sensibles.

Par conséquent, l'affectation de la valeur true à System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults ou System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults est uniquement recommandée comme une façon de déboguer temporairement une application de service. De plus, le WSDL pour une méthode qui retourne des exceptions managées non prises en charge de cette façon ne contient pas le contrat pour le FaultException de type ExceptionDetail. Les clients doivent attendre une erreur SOAP inconnue (retournée aux clients WCF comme objets System.ServiceModel.FaultException) pour obtenir correctement les informations de débogage.

Pour envoyer une erreur SOAP non déclarée, levez un objet System.ServiceModel.FaultException (autrement dit, pas le type générique FaultException) et passez la chaîne au constructeur. Cette exception est exposée aux applications clientes WCF en tant qu'exception System.ServiceModel.FaultException levée où la chaîne est disponible en appelant la méthode System.ServiceModel.FaultException.ToString.

ms732013.note(fr-fr,VS.100).gifRemarque :
Si vous déclarez une erreur SOAP de type chaîne et que vous la levez ensuite dans votre service en tant que FaultException où le paramètre de type est un System.String, la valeur de chaîne est assignée à la propriété System.ServiceModel.FaultException.Detail et n'est pas disponible à partir de System.ServiceModel.FaultException.ToString.

Gestion des erreurs

Sur les clients WCF, les erreurs SOAP qui se produisent pendant la communication et qui concernent les applications clientes sont levées en tant qu'exceptions managées. Bien que de nombreuses exceptions puissent se produire durant l'exécution d'un programme, les applications qui utilisent le modèle de programmation WCF peuvent s'attendre à gérer des exceptions des deux types suivants suite à la communication.

Les objets TimeoutException sont levés lorsqu'une opération dépasse le délai d'attente spécifié.

Les objets CommunicationException sont levés lorsqu'il existe une condition d'erreur de communication récupérable sur le service ou le client.

La classe CommunicationException a deux types dérivés importants, FaultException et le type FaultException générique.

Les exceptions FaultException sont levées lorsqu'un écouteur reçoit une erreur inattendue ou qui n'est spécifiée dans le contrat d'opération ; habituellement, cela se produit lorsque l'application est déboguée et que le service a la propriété System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults définie à true.

Les exceptions FaultException sont levées sur le client lorsqu'une erreur spécifiée dans le contrat d'opération est reçue en réponse à une opération bidirectionnelle (autrement dit, une méthode avec un attribut OperationContractAttribute ayant la valeur false affectée à la propriété IsOneWay).

ms732013.note(fr-fr,VS.100).gifRemarque :
Lorsqu'un service WCF a la propriété System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults ou System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults définie à true, le client subit l'erreur en tant que FaultException non déclarée de type ExceptionDetail. Les clients peuvent intercepter cette erreur spécifique ou gérer l'erreur dans un bloc catch pour FaultException.

En général, seules les exceptions FaultException, TimeoutException et CommunicationException sont dignes d'intérêt pour les clients et les services.

ms732013.note(fr-fr,VS.100).gifRemarque :
D'autres exceptions, bien sûr, se produisent. Les exceptions inattendues incluent des défaillances catastrophiques telles que System.OutOfMemoryException ; en général, les applications ne doivent pas intercepter de telles méthodes.

Interception des exceptions dans l'ordre correct

Étant donné que FaultException dérive de FaultException et que FaultException dérive de CommunicationException, il est important d'intercepter ces exceptions dans l'ordre approprié. Si, par exemple, vous avez un bloc try/catch dans lequel vous interceptez d'abord CommunicationException, toutes les erreurs SOAP spécifiées et non spécifiées sont gérées à cet emplacement ; les blocs catch suivants destinés à gérer une exception FaultException personnalisée ne sont jamais appelés.

Souvenez-vous qu'une opération peut retourner une quantité d'erreurs spécifiées quelconque. Chaque erreur est un type unique et doit être gérée séparément.

Gestion des exceptions lors de la fermeture du canal

Une grande partie de la discussion précédente traite des erreurs envoyées durant le traitement des messages d'application, autrement dit des messages envoyés explicitement par le client lorsque l'application cliente appelle des opérations sur l'objet client WCF.

Même avec les objets locaux, l'élimination de l'objet peut déclencher ou masquer des exceptions qui se produisent pendant le processus de recyclage. Quelque chose de semblable peut se produire lorsque vous utilisez des objets clients WCF. Lorsque vous appelez des opérations, vous envoyez des messages sur une connexion établie. La fermeture du canal peut lever des exceptions si la connexion ne peut pas être fermée proprement ou si elle est déjà fermée, même si toutes les opérations ont été retournées correctement.

En général, les canaux d'objets clients sont fermés dans les cas suivants :

Dans tous les cas, la fermeture du canal fait en sorte que celui-ci commence à fermer tous les canaux sous-jacents qui peuvent envoyer des messages pour prendre en charge la fonctionnalité complexe au niveau application. Par exemple, lorsqu'un contrat requiert des sessions, une liaison tente d'établir une session en échangeant des messages avec le canal de service jusqu'à ce qu'une session soit établie. Lorsque le canal est fermé, le canal de session sous-jacent signale au service que la session est terminée. Dans ce cas, si le canal a déjà abandonné, est déjà fermé ou est inutilisable (par exemple, lorsqu'un câble réseau est débranché), le canal client ne peut pas signaler au canal de service que la session est terminée et une exception peut être déclenchée.

Abandon du canal si nécessaire

La fermeture du canal pouvant également lever des exceptions, en plus d'intercepter les exceptions dans l'ordre correct il est important d'abandonner le canal utilisé pour effectuer l'appel dans le bloc catch.

Si l'erreur achemine des informations d'erreur spécifiques à une opération et qu'il est encore possible que d'autres puissent l'utiliser, il n'est pas nécessaire d'abandonner le canal (bien que ces cas soient rares). Dans tous les autres cas, il est recommandé d'abandonner le canal. Pour obtenir un exemple qui illustre tous ces points, consultez Expected Exceptions.

L'exemple de code suivant indique comment gérer des exceptions SOAP dans une application cliente de base, y compris une erreur déclarée et une erreur non déclarée.

ms732013.note(fr-fr,VS.100).gifRemarque :
Cet exemple de code n'utilise pas la construction using. La fermeture des canaux pouvant lever des exceptions, il est recommandé que les applications créent tout d'abord un client WCF, puis ouvrent, utilisent et ferment le client WCF dans le même bloc try. Pour plus d'informations, consultez Vue d'ensemble d'un client WCF et Avoiding Problems with the Using Statement.

Imports System
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports Microsoft.WCF.Documentation

Public Class Client
  Public Shared Sub Main()
    ' Picks up configuration from the config file.
    Dim wcfClient As New SampleServiceClient()
    Try
      ' Making calls.
      Console.WriteLine("Enter the greeting to send: ")
      Dim greeting As String = Console.ReadLine()
      Console.WriteLine("The service responded: " & wcfClient.SampleMethod(greeting))

      Console.WriteLine("Press ENTER to exit:")
      Console.ReadLine()

      ' Done with service. 
      wcfClient.Close()
      Console.WriteLine("Done!")
    Catch timeProblem As TimeoutException
      Console.WriteLine("The service operation timed out. " & timeProblem.Message)
      Console.ReadLine()
      wcfClient.Abort()
    Catch greetingFault As FaultException(Of GreetingFault)
      Console.WriteLine(greetingFault.Detail.Message)
      Console.ReadLine()
      wcfClient.Abort()
    Catch unknownFault As FaultException
      Console.WriteLine("An unknown exception was received. " & unknownFault.Message)
      Console.ReadLine()
      wcfClient.Abort()
    Catch commProblem As CommunicationException
      Console.WriteLine("There was a communication problem. " & commProblem.Message + commProblem.StackTrace)
      Console.ReadLine()
      wcfClient.Abort()
    End Try
  End Sub
End Class

Voir aussi

Tâches

Expected Exceptions
Avoiding Problems with the Using Statement

Référence

FaultException
FaultException
System.ServiceModel.CommunicationException