2009-07-10 9 views
3

Je suis sûr que je connais déjà la réponse, mais je suis toujours curieux de savoir quelle est l'opinion sur la gestion d'une erreur dans un bloc Try, Catch, Finally - mais quand vous vous répétez.Throw Exception VS Return Erreur dans un Try, Catch, Enfin

BTW - Je ne parle pas de l'entrée utilisateur - mais en utilisant que pour un exemple parce qu'il est clair et court

ce bit de Tenir compte code ...

try {  
    if (success) { 
     return someSuccessMessage; 
    } 
    else { 
     logError("User input not correct format"); 
     return someErrorMessage; // repeats itself 
    } 
} 
catch (Exception ex) { 
    logError(ex.Message); 
    return someErrorMessage; // repeats itself 
} 

Say nous avons une fonction qui, si elle échoue, nous voulons retourner un message d'erreur parce que l'exception n'est pas pertinente - notre fonction n'a pas fonctionné et l'utilisateur n'a pas besoin de détails supplémentaires. J'ai toujours eu la conviction que si vous pouvez gérer l'erreur, évitez l'exception - car ce n'est plus exceptionnel, mais je me demandais l'opinion d'éviter de vous répéter aussi ... Vous pourriez faire le ci-dessous pour éviter de vous répéter ...

try {  
    if (success) { 
     return someSuccessMessage; 
    } 
    else { 
     throw new Exception("User input not correct format"); 
    } 
} 
catch (Exception ex) { 
    logError(ex.Message); 
    return someErrorMessage; 
} 

Ce n'est pas le meilleur exemple, mais j'allais par souci de concision pour faire le point de répéter le code.

Les exceptions sont connues pour subir une pénalité de performance, mais quelles sont les réflexions sur une telle situation?

+0

Ceci est un exemple classique d'exceptions abus pour le flux de contrôle, discuté ici [Pourquoi ne pas utiliser les exceptions comme flux de contrôle régulier?] (Http://stackoverflow.com/q/729379/2444725) – Lightman

Répondre

3

IMO, une exception doit être levée uniquement lorsqu'elle est en dehors de la situation corrigible. L'utilisateur qui saisit un format incorrect est connu et ne devrait pas lancer d'exception.

Traitez Exception comme c'est catastrophique (centre de données sur le feu, tremblement de terre, etc.). De cette façon, vous verrez la différence entre gérer "erreur régulière" et "Exception".

Et oui, jeter et attraper Exception coûtent beaucoup de performance, le mieux est de les éviter.

0

dans ce cas, je dirais plutôt try/catch est inutile, comme si est plus de traiter de manière adéquate votre erreur

mais le fond est le style i beleive doit être utilisé pour des situations plus compliquées

4

Je remets en question la séparation des préoccupations ici. À moins que cette fonction ne fasse partie de l'interface utilisateur, elle ne devrait pas se préoccuper des messages d'erreur. Il devrait lancer des exceptions à la place. L'appelant de cette méthode, s'il fait partie de l'interface utilisateur, peut vouloir générer un message d'erreur pour l'affichage. Si l'appelant était un service Web, il voudrait produire une erreur SOAP, qui pourrait ne pas utiliser le même message (s'il utilisait un message quelconque).

Je vous suggère fortement de vous connecter ex.ToString() et non ex.Message.

1

Dans votre cas, je voudrais juste retourner le message d'erreur (premier exemple), car lancer une exception seulement pour l'attraper 3 ligne ci-dessous semble un peu étrange.

Une chose complètement différente est que j'évite habituellement de renvoyer des codes d'erreur quand c'est possible - quand j'ai une situation d'erreur, je traverse une exception et je l'attrape au plus haut niveau possible. De cette façon, le code n'est pas encombré de gestion des erreurs partout et il est beaucoup plus facile de voir la logique métier.Dans votre cas (si vous le contrôlez bien sûr) la méthode qui renvoie le succès pourrait avoir levé une exception en cas d'échec, et vous n'auriez pas à poser cette question du tout :)

Il est vrai que les exceptions sont cher en C#, donc ils ne devraient pas être abusés. Cela dit, quand vous avez une erreur, les 50 ms de performances sont généralement hors de propos, alors j'ai tendance à les utiliser pour garder le code propre.

+0

J'aurais dû poster un exemple plus complexe - Le court exemple est juste pour l'illustrer - je parle d'un exemple plus grand avec plus de choses en cours. Essayer d'éviter de répéter le code de gestion des erreurs. Merci pour la réponse si – Hugoware

1

Je suis d'accord avec votre logique dans votre exemple, mais quelle exception pensez-vous que vous gérez dans votre bloc de gestion des exceptions par rapport à votre test programmatique? Je soupçonne que votre bloc de gestion des exceptions est vraiment "juste au cas où quelque chose se produirait". Donc, cela revient vraiment à la règle de gestion des exceptions.

Si vous n'avez pas besoin de gérer une exception et que ce n'est pas le cas pour une limite d'architecture distincte, ne la gérez pas. Si c'est sur le bord d'une limite de composant, vous pouvez vouloir l'envelopper, en plaçant l'original dans l'exception interne. Si la fonctionnalité était appelée à partir du code, vous voudriez soit tester le résultat avec une représentation d'état telle qu'une réponse (HRESULT en est un excellent exemple.) 0 == SUCCESS,! = 0 == échec) utiliser des exceptions.

Si vous validez l'entrée de l'utilisateur sur une interface utilisateur, vous pouvez utiliser simplement des codes d'état logique et de retour pour aider à communiquer l'erreur à l'utilisateur.

Enfin, pensez aussi à la localisation. Si vous redirigez un message d'erreur en anglais dans le système et que vous le présentez à votre utilisateur francophone, ce qui ne serait pas utile et vous ne voulez pas commencer à analyser les chaînes de votre interface utilisateur pour générer la version française. aller aussi longtemps que la charge utile de l'exception a suffisamment d'informations pour générer un message d'erreur utile pour l'utilisateur de prendre des mesures correctives.

Utilisez le code d'état lorsque vous avez un couplage étroit entre les composants et que le composant appelant sait quoi faire dans les différentes conditions d'état.

BTW Vous souhaiterez peut-être enregistrer la trace de la pile ainsi que le message en utilisant ToString() car cela vous donnera des informations plus utiles pour résoudre le problème.

HTH

+0

Merci pour votre réponse - BTW - ce n'est pas du vrai code - c'était simplement pour illustrer le point :) – Hugoware

1

Extrait du code dupliquée sur en fonction, si vous vous sentez-vous répéter est un problème.

error_code_t fail (string message) { 
    logError(message); 
    return someErrorMessage; 
} 

// ... 

try {  
    if (success) { 
     return someSuccessMessage; 
    } 
    else { 
     return fail("User input not correct format"); 
    } 
} 
catch (Exception ex) { 
    return fail(ex.Message); 
} 

Pour être honnête, je ne m'inquiéterais pas de dupliquer quelques lignes dans la même fonction.

+0

Je ne suis pas d'accord sur la dernière phrase. Il peut sembler "pas si important" à première vue d'éliminer la duplication de quelques lignes, mais d'imaginer la même "répétition légère" dans 10 méthodes différentes. La duplication est mauvaise. Comme dit St Exupery: la perfection n'est pas quand il n'y a rien à ajouter, mais quand il n'y a rien à enlever. –

Questions connexes