2010-11-15 30 views
1

Si une fonction a 2 arguments et que les deux produisent des exceptions, dans quel ordre les auriez-vous levés et où les définiriez-vous?Ordre d'exception lorsque multiple est possible

Ceci est apparu lorsque j'écrivais un test pour une fonction qui prendrait un répertoire sur disque et le comprimerait dans un fichier. Par exemple:

void Compress(string dirPath, string filePath); 

Je n'ai pas encore écrit la fonction et je mets mes tests en place. Le fait est que, si le chemin de répertoire n'existe pas, j'aurais une exception pour un répertoire manquant et si le fichier avait des permissions d'écriture comme cela que je l'ai fait pour montrer une exception. Cependant, que se passe-t-il si les deux chemins provoquent des exceptions? Est-ce que je lancerais le premier, le second, un autre troisième, ou est-ce un état inconnu? Nous avions également envisagé d'avoir une seule exception pour dire "Quelque chose a cassé", mais le message serait différent dans chaque cas, donc cela n'aide pas vraiment. J'ai pensé à plusieurs façons de contourner le problème, comme lancer toujours en fonction du traitement de gauche à droite des arguments, ou en indiquant "Si dirPath est invalide, X est levé sinon si filePath est invalide, alors Y est levé" et plaçant cela avec la définition d'interface de sorte que celui qui l'implémente devrait (espérons-le) suivre cette spécification.

Je me demandais simplement quelle approche adopteraient les gens à ce problème.

Pour référence, ceci est en C# mais je ne pense pas que ce soit un problème spécifique à la langue.

+1

Je pense que c'est surtout la préférence, mais si c'était moi, je mettrais dans l'ordre le plus logique pour moi. Dans ce cas, vous voulez compresser un dossier, donc vous devez d'abord le chercher et s'il y a un problème, vous ne devriez pas vous préoccuper du problème avec le fichier de destination, car vous n'y arriverez même pas. –

+0

@kylep: complètement d'accord; vois ma réponse. –

Répondre

1

Je le laisserais non spécifié. La documentation peut indiquer:

Les exceptions possibles sont les suivantes: X si dirPath n'est pas valide; Y si filePath est invalide.

S'il existe un test unitaire où les deux sont invalides, il peut passer tant que l'une des deux exceptions est levée. En réalité, tout ce qui dépend réellement de l'exception qui se produit lorsqu'il y a plusieurs problèmes d'exception n'est pas une bonne idée.

+0

C'est une autre option que j'ai considérée mais j'ai deux problèmes avec cette approche: Un problème est que nos tests unitaires ne permettent pas plus d'une exception possible (bien que cela soit réparable). L'autre problème est que je me sens un peu mal à l'aise avec le code qui peut retourner ceci ou que pour la même entrée. Je pense que je préférerais que la commande soit spécifiée. –

+0

Bien que je ne sois pas complètement à l'aise avec ça, c'est celui avec lequel je suis allé après d'autres discussions avec des collègues. Nous sommes arrivés à cette conclusion puisque nous n'avions pas vraiment le contrôle total sur l'ordre dans lequel les exceptions étaient nécessairement imposées. Cependant, ces réponses et McWafflestix m'ont aidé. Merci. –

2

Lors de la détermination de l'ordre d'exception, vous devez déterminer l'ordre logique d'échec. Ainsi, dans votre exemple, si le répertoire n'existe pas et que l'autorisation d'écriture de fichier n'est pas autorisée, il n'est pas déraisonnable de s'attendre à ce que votre code vérifie d'abord l'existence du répertoire avant de tenter de créer le fichier cible; par conséquent, cette exception devrait être levée du code qui vérifiera l'existence du répertoire, ce qui sera fait en premier.

Bien sûr, si vous avez une raison spécifique pour changer l'ordre des opérations (créer d'abord le fichier d'écriture, puis vérifier le répertoire source), c'est parfaitement bien; le fait est que, cependant, l'un ou l'autre chemin lancera une exception, ce qui indique que QUELQUE CHOSE a mal tourné avec l'opération; comment le code appelant gère le code appelant. Si vous voulez intercepter un type d'exception récupérable (filenotwritable, par exemple) et gérer cela spécifiquement, puis piéger une exception générale pour tout le reste, c'est bien; votre application doit définir le protocole par lequel elle considère et gère les exceptions du code appelé.