API Conception: Comment classes distinctes d'erreurs être traitées à partir d'un appel XMLHTTP asynchrone?

voix
0

J'ai une application VB6 héritage qui a besoin de faire des appels asynchrones à un service Web. Le service Web offre une searchméthode permet aux utilisateurs finaux d'interroger une base de données centrale et afficher les résultats de l'application. J'utilise le MSXML2.XMLHTTPfaire les demandes, et ont écrit une SearchWebServiceclasse qui encapsule l'appel de service Web et du code pour gérer la réponse asychronously.

À l' heure actuelle, la SearchWebServicepose l' un des deux événements à l'appelant: SearchCompletedet SearchFailed. Un SearchCompletedévénement est déclenché contenant les résultats de la recherche dans un paramètre à l'événement si l'appel se termine avec succès. A SearchFailedest élevé quand tout type de défaillance est détectée, ce qui peut être quelque chose à partir d' une URL mal formatée (cela est possible parce que l'URL est configurable par l' utilisateur), à des erreurs de réseau de bas niveau tels que « Host not found », HTTP des erreurs telles que les erreurs internes du serveur. Il retourne une chaîne de message d'erreur à l'utilisateur final (qui est extrait du corps de réponse du service Web, le cas échéant, ou du texte du code d'état HTTP si la réponse n'a pas de corps, ou traduit à partir du code d'erreur réseau si une erreur réseau se produit).

En raison de diverses exigences de sécurité, l'application appelante n'a pas accès au service Web directement, mais il accède à la place via un serveur Web proxy en cours d' exécution sur le site du client, ce qui donne accès au service Web réel par l' intermédiaire d' un VPN. Cependant, le SearchWebServicene sait pas que l'application appelante accède au service Web via un proxy: il vient de donner une URL et dit de faire la demande. L'existence de la procuration est une exigence de niveau d'application.

Le problème est que du point de vue de l'utilisateur final, il est important que l'application appelante pouvoir faire la distinction entre les erreurs de réseau à faible niveau par rapport à des erreurs HTTP du service Web, et de distinguer les erreurs de proxy à partir des erreurs de serveur Web distant. Par exemple, l'application a besoin de savoir si une demande a échoué parce que le serveur proxy est en panne, ou parce que le service Web distant que le proxy accède est en panne. Un message spécifique à l'application doit être présenté à l'utilisateur final dans chaque cas, comme « Rechercher serveur proxy de service Web semble être en panne. Le serveur proxy peut être redémarré » et « Le proxy est actuellement en cours d'exécution, mais la télécommande serveur web semble être indisponible. S'il vous plaît contacter (nom de la personne responsable du serveur Web distant) « . Je pourrais gérer cela directement dans laSearchWebService classe, mais il semble erroné de générer ces messages d'erreur spécifiques à l'application d'une telle classe générique (et la classe peut être utilisé dans des environnements qui ne nécessitent pas un proxy, où les messages d'erreur ne seraient plus de sens).

Cette distinction est importante pour le dépannage: un problème de serveur proxy peut généralement être résolu par le client, mais une erreur de serveur Web distant doit manipulé par un tiers.

Je pensais une façon de gérer ce serait d'avoir la SearchWebServiceclasse détecter différents types d'erreurs et soulèvent différents événements dans chaque cas. Par exemple, au lieu d'un seul SearchFailedévénement, je pourrais avoir un NetworkErrorévénement pour les erreurs de réseau de bas niveau (qui indiquerait un problème d' accès au serveur proxy), un ConfigurationErrorévénement pour les propriétés non valides sur la SearchWebServiceclasse ( par exemple, le passage d' un URL mal formaté) , et ServiceErrordes erreurs qui se produisent sur le serveur Web distant (ce qui implique que le proxy fonctionne correctement , mais le serveur distant a retourné une erreur).

Maintenant que j'y pense, il y a aussi un scénario d'erreur supplémentaire: il pourrait être possible que le serveur proxy fonctionne correctement, mais le serveur Web à distance est en panne ou le serveur proxy a été mal configuré.

L'approche de l'utilisation de plusieurs événements d'erreur pour classer les différentes classes d'erreur une solution raisonnable à ce problème? Pour le dernier scénario (le proxy est en cours d'exécution, mais le serveur distant ne peut pas être atteint), je suppose que je dois configurer le proxy pour renvoyer un code d'erreur HTTP spécifique afin que le client peut détecter cette situation (à savoir quelque chose de plus précis que une réponse 500).

Au départ , je gardais le seul SearchFailedévénement et simplement ajouté un montant supplémentaire de errorCodeparamètre à l'événement, mais qui a rapidement eu désordre, surtout dans les cas où il n'y avait pas un code d'erreur logique d'utiliser (comme si le VB6 déclenche une erreur « réelle », à savoir si la classe XMLHTTP est pas enregistré).

Créé 27/08/2009 à 05:38
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
1

Je pense que quelques idées que je l'ai utilisé avec Java exceptions peuvent s'appliquer ici.

Avoir un grand nombre de différentes exceptions est assez compliqué, mais nous devons donner suffisamment de détails pour l'utilisateur que nous ne voulons pas perdre des informations.

Par conséquent, j'ai un petit nombre d'exceptions, que je suppose que correspondrait à vos événements:

  • InvalidRequestEvent: Utilisé lorsque l'utilisateur spécifie une mauvaise information
  • TransientErrorEvent: utilisé quand il y a des problèmes d'infrastructure quand une nouvelle tentative pourrait fonctionner.

J'ai tendance à travailler dans des environnements où nous avons des clusters de serveurs, donc si une requête utilisateur frappe un serveur de mourir s'il resoumet il va probablement obtenir un bon, donc de son point de vue d'une nouvelle tentative simple fonctionne souvent. Cependant, parfois l'erreur est un service tel que le réseau ou la base de données et dans ce cas, l'utilisateur a besoin d'informations de diagnostic pour faire rapport au service d'assistance. Par conséquent, nous devons décider de l'information supplémentaire à mettre dans l'exception. Ceci est (si je comprends bien) votre question.

Dans le cas de InvalidRequestException nous parierais donner des informations sur les problèmes avec l'entrée. Il pourrait être sur les lignes de « parenthese Mismatched » ou « CUTSOMER colonne inconnue dans le tableau ORDER ». Dans le cas de TransientErrorException il pourrait être « serveur proxy est en panne ».

Maintenant, en fonction de vos exigences exactes que vous ne pouvez pas réellement choisir de mettre ce texte dans l'exception, mais plutôt un numéro d'erreur que la couche de présentation se transforme en une chaîne spécifique aux paramètres régionaux (anglais, français ...).

Donc, soit l'exception peut contenir quelque chose comme ça (désolé pour cette syntaxe Java, mais j'espère que l'idée est claire):

BaseException {
    String ErrorText;     // the error text itself

    // OR if you want to allow for internationaliation

    int ErrorCode;        // my application specific code, corresponds to text held by the UI
    String[] params;      // specific parameters to be substitued in the error text
                          // CUTSOMER and ORDER in my example above


    int SystemErrorCode;    // If you have an underlying error code it goes here


    String SystemErrorText; // any further diagnoistic you might need to give to 
                            // the user so that they can report the problem to the 
                            // help desk.

    // OR instead of the text (this is something I've seen done)

    int SystemErrorTag;     // A unique id for this particular error problem. 
                            // This server systems will label their message in the
                            // server logs. Users just tell the help desk this number
                            // they don't need to read detailed server error text.

}

Créé 27/08/2009 à 08:03
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more