IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Comment identifier une exception? Peut on obtenir un numéro?


Sujet :

C#

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Par défaut Comment identifier une exception? Peut on obtenir un numéro?
    Bonjour à tous,

    Je me pose une question concernant les exceptions. Est il possible d'identifier uen exception?
    Prenons un exemple. J'utilise la fonction File.Copy(), celle ci peut lever un certain nombre d'exceptions, comme System.IO.IOException par exemple.
    Hors, si le disque est plein (quota exceeded) ou si le fichier existe déjà, j'ai le même type d'exception "System.IO.IOException". Peut on les différencier autrement que part le message car je ne trouve pas ça très fiable...
    Je ne sais pas, soit en récupération le code (mais apparament ça n'existe pas), soit autrement.
    Quelqu'un aurait il une piste svp?

    Merci d'avance

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    par le message c'est en effet pas terrible, il peut changer selon la langue de l'os ...

    tu peux regarder dans ex.data s'il y a quelque chose ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut
    Chaque classe/méthode est documentée dans msdn. Tu as donc la liste des exceptions disponibles dans chaque cas...
    Peut-être qu'avec les inner-exceptions tu pourrais avoir d'autres infos, mais tu vas devoir coder un truc pour gérer ça... avec le Catch, tu n'as pas le choix. Mais je dis ça sans être convaincu moi-même.
    Si le cas que tu as cité est ton cas réel, alors fait un File.Exists et tu élimineras cette erreur...

  4. #4
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par takinelinfo Voir le message
    Bonjour à tous,

    Je me pose une question concernant les exceptions. Est il possible d'identifier uen exception?
    Prenons un exemple. J'utilise la fonction File.Copy(), celle ci peut lever un certain nombre d'exceptions, comme System.IO.IOException par exemple.
    Hors, si le disque est plein (quota exceeded) ou si le fichier existe déjà, j'ai le même type d'exception "System.IO.IOException". Peut on les différencier autrement que part le message car je ne trouve pas ça très fiable...
    Je ne sais pas, soit en récupération le code (mais apparament ça n'existe pas), soit autrement.
    Quelqu'un aurait il une piste svp?

    Merci d'avance
    Tu es sur qu'il n'y a pas d'InnerException associée ?

  5. #5
    Membre Expert Avatar de Er3van
    Homme Profil pro
    Architecte Logiciel
    Inscrit en
    Avril 2008
    Messages
    1 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte Logiciel
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2008
    Messages : 1 430
    Par défaut
    Et si tu fais
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    GetBaseException().GetType()
    sur ton exception, tu obtiens une différence selon les cas ?

    Si oui c'est qu'à un moment donné les exceptions sont encapsulées alors qu'elle ne le devrait pas.

    Il est possible que tu ne puisses pas le faire à cet endroit là, mais que tu sois obligé de gérer ton propre type d'exception par rapport à ta connaissance de l'erreur. (Pour peu que ça soit à deux endroits différent dans ta méthode, sinon là je sèche, sauf à trier par message)

  6. #6
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Par défaut
    Une chose non garantie du tout (et je tiens à le préciser), serait de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int error = Marshal.GetLastWin32Error();
    mais ce bout de code n'est pas garanti du tout dans la mesure ou une autre erreur Win32 peut apparaître entre temps et qu'il faut que ce soit de l'Interop qui effectue la copie de fichier (et que la récupération des erreurs soit activée).

    Bref, beaucoup de si, donc la question est : pourquoi vouloir distinguer les cas ?
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  7. #7
    Membre éprouvé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Par défaut
    Ajoute un test File.Exists(...), si ça pète, tu sauras pourquoi. Les exceptions c'est beau, mais ça n'empêche pas de faire des checks préliminaires !

  8. #8
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    j'ai déjà entendu "si bouygues faisait des maison comme un développeur fait un logiciel, les maisons s'écouleraient très vite, il y aura des portes au plafond etc..."

    et en effet si on transpose ce qu'on fait tous dans d'autres métiers ça peut faire peur
    genre le pilote d'avion qui soit vérifie qu'il a le plein avant de décoller, et que les ailes sont là ou alors une fois l'avion crashé il cherche pourquoi il est tombé
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  9. #9
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    j'ai déjà entendu "si bouygues faisait des maison comme un développeur fait un logiciel, les maisons s'écouleraient très vite, il y aura des portes au plafond etc..."
    Ouais ..... si les développeurs pouvaient faire des maisons au même tarif Bouygues, on en reviendrait au bon temps des années 90, avec les prix de journées associés (et je roulerais de nouveau dans une voiture "avec 6 cylindres refroidis par air à l'arrière" plutôt que dans un véhicule de fabrication japonaise carburant au mazout )

    Parole de vieil informatico de presque 50 ans

  10. #10
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut
    @ Arnard, c'est ce que j'ai dit plus haut....

    @Pol63... Tu n'imagines même pas la longueur de la checklist avant décollage... plus l'avion est moderne, plus compliqué et truffé d'informatique, plus cette liste s'allonge !!! l'informatique est une grosse source de pannes dans les avions... et les voiture maintenant... vous avez entendu parler des cerveaux de renault qui se bloquait et coupait toute l'aide à la conduite ? plus d'abs, plus de d.a., plus rien en fait, un bolide sans commande ! (chouette on aura l'impression de conduire des dragsters ! en moins vite...)


    Pour en revenir au problème, je ne sais plus qui en a parler, mais du codage "défensif" te permet d'éviter des exceptions - qui, comme leur nom l'indique, doivent rester exceptionnelles. Un test pour s'assurer que tout est ok consomme moins qu'un CATCH !!! efficacité... .Net = VM => lenteur ; donc au cerveau de commander et non au clavier !

  11. #11
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par kheironn Voir le message
    Pour en revenir au problème, je ne sais plus qui en a parler, mais du codage "défensif" te permet d'éviter des exceptions - qui, comme leur nom l'indique, doivent rester exceptionnelles. Un test pour s'assurer que tout est ok consomme moins qu'un CATCH !!! efficacité... .Net = VM => lenteur ; donc au cerveau de commander et non au clavier !
    C'est vrai dans le cas général, mais le cas précis de l'IO disque est particulier, parce que rien n'empêche une autre appli (ou l'user va l'explorateur) de supprimer un fichier entre un File.Exists et un File.Open. Donc il faut try catcher.

    Et la problématique de perf n'a pas lieu, ici. Les coûts d'attente d'IO sont bieeeen supérieurs au surcoût qui survient lorsque la mécanique de catch se déclenche.

  12. #12
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut
    Citation Envoyé par Guulh Voir le message
    C'est vrai dans le cas général, mais le cas précis de l'IO disque est particulier, parce que rien n'empêche une autre appli (ou l'user va l'explorateur) de supprimer un fichier entre un File.Exists et un File.Open. Donc il faut try catcher.

    Et la problématique de perf n'a pas lieu, ici. Les coûts d'attente d'IO sont bieeeen supérieurs au surcoût qui survient lorsque la mécanique de catch se déclenche.
    Je n'ai jamais dit qu'il ne fallait pas faire de Try-Catch... justement pour ce genre de cas. J'ai simplement dit qu'il était possible de prendre ses précautions... 2 capottes valent mieux qu'une ( mauvais exemple...)

  13. #13
    Membre éclairé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Par défaut
    Citation Envoyé par kheironn Voir le message
    Pour en revenir au problème, je ne sais plus qui en a parler, mais du codage "défensif" te permet d'éviter des exceptions - qui, comme leur nom l'indique, doivent rester exceptionnelles. Un test pour s'assurer que tout est ok consomme moins qu'un CATCH !!! efficacité... .Net = VM => lenteur ; donc au cerveau de commander et non au clavier !
    Moé... Il existe une "mode", un "phénomene", une "théorie", "religion" appelez ca comme vous voulez, qui prone la Programmation par Exception.

    Mis a part le nom, on ne gagne rien a laisser les exceptions etre exceptionnelles...

    Ce n'est qu'un saut conditionel, si quelque part dans l'éxécution, quelque chose ce passe "mal". Et c'est plus "couteux" au final de faire Exist+try-catch qu'un simple try-catch.
    Ton simple "test" va déclencher tout une batterie de fonctions, tests et procédure, qui vont passer par l'API windows, puis dans le controlleur disque, etc...

    En plus, quand tu veux lire un fichier, il y a déja un if(file.Exists), ou quelque chose d'approchant, et c'est d'ailleur lui qui va envoyer l'exception.
    Donc ce n'est pas 2 capotes, mais 3 ou plus ici !

    Les exceptions se rapprochent des interruptions, si certains d'entre vous on fait de la programmation sur microcontroleurs par exemple.


    On ne gagne rien en pure efficacité a faire du codage "défensif".
    Parceque oui, en plus, en .NET, l'exécution d'une portion de code est aussi rapide qu'avec du C++ compilé !
    Il n'y a pas de VM, ca c'est pour du Java. En .NET, il y a le compileur JIT.
    (Si je dit portion de code, c'est que suivant différentes options, le JIT va compiler en code natif tout ou une partie du code MSIL généré).


    Apres, ce n'est qu'une question de gout, et de philosophie (et en général de compréhension et de lisiblité). Moi personellement je n'aime pas, mais ca ne reste pas "mauvais" de faire ca pour autant.

  14. #14
    Membre éclairé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Par défaut
    Pour répondre a la question initiale, si tu veux des messages plus explicites, il va falloir passer par l'API windows, a coup de DllImport, de maniere a avoir les primitives pour lire/écrire dans des fichiers, et les primitves pour les messages d'erreurs, notament GetLastError()

    D'ailleur il est peut etre possible de n'utiliser que GetLastError, mais je ne le garantit pas.

  15. #15
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par cs_ntd Voir le message
    D'ailleur il est peut etre possible de n'utiliser que GetLastError, mais je ne le garantit pas.
    Le retour de GetLastError peut être intégré nativement aux appels P/Invoke.

    C'est une fonctionnalité de base; elle est décrite dans l'attribut DllImport.

  16. #16
    Membre éclairé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Par défaut
    Ce que je voulais dire, c'est que je ne suis pas sur que n'utiliser QUE GetLastError soit significatif...

    Dans ma tête, je me disais que comme on est en .NET, la "LastError" ne sera peut-être pas celle que l'on cherche, et de plus, (je m'en souvient maintenant), il faut utiliser FormatMessage, pour avoir l'erreur sous une forme lisible.

    De plus, ce n'est qu'une théorie, je ne garantit pas que le message qu'on obtiendra soit plus significatif que le message de l'exception .NET.

    Sinon, le retour de GetLastError est un DWORD, donc utilisable oui, mais je ne comprend pas ce que tu veux dire par
    C'est une fonctionnalité de base; elle est décrite dans l'attribut DllImport.

  17. #17
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    IOException hérite de SystemException, qui a une propriété HResult. Cette propriété est protected (je sais pas trop pourquoi d'ailleurs), mais on peut y accéder avec la méthode Marshal.GetHRForException. Ensuite il suffit de tester la valeur du HRESULT...

    Je n'ai pas trouvé de "table de référence" des codes HRESULT, mais il suffit de tester un cas d'erreur contrôlé pour obtenir la valeur correspondante. Sinon il y a cette page qui décrit la structure d'un HRESULT...

  18. #18
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par tomlev Voir le message
    IOException hérite de SystemException, qui a une propriété HResult. Cette propriété est protected (je sais pas trop pourquoi d'ailleurs), .
    Pas illogique dans la mesure ou IOException même si elle est instanciable est plutôt destinée à être héritée (File*, Directory*, etc ...)

  19. #19
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Par défaut
    Citation Envoyé par tomlev Voir le message
    IOException hérite de SystemException, qui a une propriété HResult. Cette propriété est protected (je sais pas trop pourquoi d'ailleurs), mais on peut y accéder avec la méthode Marshal.GetHRForException. Ensuite il suffit de tester la valeur du HRESULT...

    Je n'ai pas trouvé de "table de référence" des codes HRESULT, mais il suffit de tester un cas d'erreur contrôlé pour obtenir la valeur correspondante. Sinon il y a cette page qui décrit la structure d'un HRESULT...
    C'est exactement ce que je cherchais.
    Obtenir un code, un identifiant unique par exception.
    Il ne reste plus qu'à fabriquer une table de correspondance pour les codes.
    Un grand merci.

  20. #20
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Par défaut
    Je viens de faire un test, ce n'est pas vraiment ça.
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    try
    {
       File.Copy(@"C\file1.pdf", @"C:\file2.pdf");
    }
    catch(Exception e)
    {
       var b = Marshal.GetHRForException(e);
    }

    Retour : -2147024894 -> FileNotFoundException
    Retour : -2147024784 -> IOException : Espace insuffisant sur le disque.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 19
    Dernier message: 02/10/2006, 17h19
  2. Comment identifier une machine de facon unique ?
    Par BigBenQ dans le forum Développement
    Réponses: 14
    Dernier message: 19/12/2005, 08h36
  3. comment identifier une transaction http?
    Par didier.cabale dans le forum Développement
    Réponses: 5
    Dernier message: 13/04/2005, 16h42
  4. [SqlException] comment identifier l'exception
    Par Jchasson dans le forum JDBC
    Réponses: 3
    Dernier message: 08/10/2004, 11h38
  5. Réponses: 2
    Dernier message: 28/08/2003, 00h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo