Meilleur auteur de réponses
Message d'erreur compréhensible aux utilisateurs c#

Question
-
Bonjour,
j'ai de temps en temps, j'ai le message d'erreur suivant :- Server was unable to process request. ---> Original error message: Database problem while fetch entity failed. ---> [IBM U2][UODOTNET - UNICLIENT][ErrorCode=45002] Cannot perform operation on a null recordID
Comment peux-je afficher un autre message plus compréhensible aux utilisateurs ?
Par exemple :
- Il ne faut pas trop longtemps attendre avant de valider ce formulaire : votre session a expiré
au lieu d'afficher le message ci-dessous ?
Bonne journée
- Server was unable to process request. ---> Original error message: Database problem while fetch entity failed. ---> [IBM U2][UODOTNET - UNICLIENT][ErrorCode=45002] Cannot perform operation on a null recordID
Réponses
-
Attention try/catch est un bloc d'instructions donc il faut le placer dans votre code (et non dans votre classe) en englobant la partie qui peut provoquer l'erreur afin que le catch intercepte cette erreur.
Si je comprends bien votre contexte plutôt que de relancer une exception il faut afficher le message dans 'ErrorLabel' :
protected void post_Click(object sender, System.EventArgs e) { ErrorLabel.Visible = false; if (IsValid() && Page.IsValid) { try{ // On protège l'exécution de ce code, si une erreur arrive dans ce bloc on // se rendra dans le bloc catch ScriptManager.RegisterStartupScript(this, this.GetType(), "Page", "post()", true); //appel function post() SetPageState(); Session["EntreeNouveau"] = "NouveauFormEntre"; Response.Redirect("confirmer.aspx"); }catch(Exception ex){ if(ex.ErroCode == 45002) { ErrorLabel.Text = "Il ne faut pas trop attendre..."; }else { ErrorLabel.Text = ex.Message; } ErrorLabel.Visible = true; } } }
Si vous n'êtes pas familier avec les exceptions et le try/catch je vous conseille de consulter la MSDN :
http://msdn.microsoft.com/fr-fr/library/ms173160(v=vs.80).aspx
sur le fonctionnement des exceptions et pour la référence aux instructions try/catch/finally.
Cordialement,
Yan Grenier
- Proposé comme réponse Yan Grenier - MTFC jeudi 29 novembre 2012 16:17
- Marqué comme réponse Aurel Bera mardi 4 décembre 2012 08:26
-
Yan et moi t'avons répondu sur la gestion des exceptions... le dernier message de Yan est prendre aussi en considération.
A la lecture de ton message, j'ai l'impression que ton besoin est plus général que simplement gérer des exceptions... il semble s'agir de gérer la fin de session de l'utilisateur.
Si c'est le cas, il faut prendre un peu de recul pour mettre en place un système plus global. En effet, il te faudrait gérer ce cas dans tout tes événements utilisateurs, ce qui n'est pas jouable.
J'ai trouvé quelques articles sur ce sujet qui te donneront des infos intéressantes... à toi de voir comment tu veux implémenter tout ça :
- http://aspalliance.com/520_Detecting_ASPNET_Session_Timeouts.all
- http://www.codeproject.com/Articles/15575/Detecting-Session-Timeout-and-Redirect-to-HomePage
- http://www.eggheadcafe.com/tutorials/asp-net/7262426f-3c65-4c90-b49c-106470f1d22a/build-an-aspnet-session-timeout-redirect-control.aspx
- Proposé comme réponse Hervé DORIER jeudi 29 novembre 2012 16:54
- Marqué comme réponse Aurel Bera mardi 4 décembre 2012 08:26
-
Bonjour,
Votre Exception provient d'un accès en base SQL donc il faut utiliser SqlException. A partir de cette classe d'exception, vous aurez le code d'exception. N'utilisez jamais une reconnaissance d'erreur par le message car si celui-ci est dans une autre langue, l'application ne traitera jamais votre code. Il faut impérativement utiliser ErrorCode.
La classe Exception est la haute hiérarchiquement et répond à une erreur tout genre (générique).
Est-ce que cela vous aides ?
Cordialement
Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !
- Marqué comme réponse Aurel Bera mardi 11 décembre 2012 08:28
Toutes les réponses
-
Bonjour,
A moins de ne pas avoir tout saisi il suffit d'intercepter ce message d'erreur et lever une autre exception plus compréhensible genre :
try{ ... }catch(Exception ex){ if(ex.Message.Contains("Cannot perform operation on a null recordID"){ throw new ApplicationException("Il ne faut pas trop attendre..."); }else{ throw ex; } }
Bien sur à modifier en fonction du type d'exception si elle est particulière, où si le code erreur est accessible pour isoler les différents cas à intercepter.
Après si le fait de relancer une exception n'est pas compatible avec votre code il faut corriger en fonction de vos méthodes d'affichage des erreurs, mais le principe reste le même.
Cordialement,
Yan Grenier
- Proposé comme réponse Yan Grenier - MTFC jeudi 29 novembre 2012 07:47
-
Bonjour,
Pour ma part j'éviterais
if(ex.Message.Contains("Cannot perform operation on a null recordID"){
Si c'est possible, il vaut mieux :
- Faire un try/catch sur la classe de l'exception à gérer, du style
}catch(SqlException ex){
2. Tester sur le code erreur 45002
try{ ... }catch(Exception ex){ if(ex.ErroCode == 45002) { throw new ApplicationException("Il ne faut pas trop attendre...", ex); }else{ throw; } }
Pour aller plus loin dans la gestion des Exceptions, je conseillerais de :
- Créer un constructeur ApplicationException permettant d'initialiser l'innerException avec l'exception d'origine. Cela permet de conserver la stacktrace dans les logs.
- D'éviter les "else throw ex" au profit d'un "else throw"... toujours pour une meilleure gestion de la stacktrace.
Pas contre, bien vu l'utilisation d'une classe d'exception custom "ApplicationException" qui permet de voir dans le code appelant que l'exception a déjà été gérée.
Cordialement.
- Proposé comme réponse Hervé DORIER jeudi 29 novembre 2012 13:48
-
Bonjour,
Pour ma part j'éviterais
if(ex.Message.Contains("Cannot perform operation on a null recordID"){
Si c'est possible, il vaut mieux :
- Faire un try/catch sur la classe de l'exception à gérer, du style
}catch(SqlException ex){
2. Tester sur le code erreur 45002
try{ ... }catch(Exception ex){ if(ex.ErroCode == 45002) { throw new ApplicationException("Il ne faut pas trop attendre...", ex); }else{ throw; } }
Oui c'est exact c'est pour cela que j'ai précisé "Bien sur à modifier en fonction du type d'exception si elle est particulière, où si le code erreur est accessible pour isoler les différents cas à intercepter".
Tout dépend du cas, je connais des libs qui ne fournissent aucune informations susceptible d'aider à la décision, donc il ne reste que l'analyse du texte du message (sympathique quand c'est localisé :) ).
C'est vrai que je n'ai pas spécifié le innerException comme apparemment la demande résidait essentiellement sur un changement du message d'erreur pour l'utilisateur final.
Concernant le "throw" au lieu du "throw ex" je croyais que c'était parfaitement identique : il y a une différence ?
Concernant l'utilisation d'ApplicationException c'est essentiellement une recommandation de ne pas utiliser "Exception" directement que je vois un peu partout dans les bonnes pratiques de développement où l'analyse de code.
Cordialement,
Yan Grenier
-
Bonjour Yan et Hervé,
Merci vos réponses...
Est-ce qu'il faut que je mette ce catch/try à l'endroit du bouton ?protected void post_Click(object sender, System.EventArgs e) { ErrorLabel.Visible = false; if (IsValid() && Page.IsValid) { ScriptManager.RegisterStartupScript(this, this.GetType(), "Page", "post()", true); //appel function post() SetPageState(); Session["EntreeNouveau"] = "NouveauFormEntre"; Response.Redirect("confirmer.aspx"); } }
ou bien, comme vous dites :
public partial class nouveau_utilisateur_inscriptionCodeProm : System.Web.UI.Page { try{ //... etc protected void Page_Load(object sender, System.EventArgs e) { //... etc } private void InitializeComponent() { //... etc } private void LoadPageState() { //... etc } //... etc } catch(Exception ex) { if(ex.ErroCode == 45002) { throw new ApplicationException("Il ne faut pas trop attendre...", ex); }else { throw; } } }
Bonne journée
Cordialement
-
Attention try/catch est un bloc d'instructions donc il faut le placer dans votre code (et non dans votre classe) en englobant la partie qui peut provoquer l'erreur afin que le catch intercepte cette erreur.
Si je comprends bien votre contexte plutôt que de relancer une exception il faut afficher le message dans 'ErrorLabel' :
protected void post_Click(object sender, System.EventArgs e) { ErrorLabel.Visible = false; if (IsValid() && Page.IsValid) { try{ // On protège l'exécution de ce code, si une erreur arrive dans ce bloc on // se rendra dans le bloc catch ScriptManager.RegisterStartupScript(this, this.GetType(), "Page", "post()", true); //appel function post() SetPageState(); Session["EntreeNouveau"] = "NouveauFormEntre"; Response.Redirect("confirmer.aspx"); }catch(Exception ex){ if(ex.ErroCode == 45002) { ErrorLabel.Text = "Il ne faut pas trop attendre..."; }else { ErrorLabel.Text = ex.Message; } ErrorLabel.Visible = true; } } }
Si vous n'êtes pas familier avec les exceptions et le try/catch je vous conseille de consulter la MSDN :
http://msdn.microsoft.com/fr-fr/library/ms173160(v=vs.80).aspx
sur le fonctionnement des exceptions et pour la référence aux instructions try/catch/finally.
Cordialement,
Yan Grenier
- Proposé comme réponse Yan Grenier - MTFC jeudi 29 novembre 2012 16:17
- Marqué comme réponse Aurel Bera mardi 4 décembre 2012 08:26
-
Merci Yan
c'est très apprécié...
avecif (ex.ErrorCode == 45002)
j'ai un message d'erreur
'System.Exception' ne contient pas une définition pour 'ErrorCode' et aucune méthode d'extension 'ErrorCode' acceptant un premier argument de type 'System.Exception' n'a été trouvée (une directive using ou une référence d'assembly est-elle manquante ?)
C’est pourquoi? Vous avez une idée...
Merci
Cordialement
-
Oui, il y a une différence notable, et importante si tu souhaite gérer ton exception sur plusieurs niveaux.
//Cas 1 try{ ... }catch(Exception ex){ throw ex; // L'exception ex est remontée à l'appelant, mais la stack est perdue. } //Cas 2 try{ ... }catch(Exception ex){ throw; // L'exception ex est remontée à l'appelant en conservant la stack. }
Dans le second cas, si tu affiche la stack trace dans la page HTML, tu verras toute la pile de l'exception.
Dans le premier cas, tu n'auras que la pile à partir de la méthode qui a envoyé le "throw ex".
-
-
Yan et moi t'avons répondu sur la gestion des exceptions... le dernier message de Yan est prendre aussi en considération.
A la lecture de ton message, j'ai l'impression que ton besoin est plus général que simplement gérer des exceptions... il semble s'agir de gérer la fin de session de l'utilisateur.
Si c'est le cas, il faut prendre un peu de recul pour mettre en place un système plus global. En effet, il te faudrait gérer ce cas dans tout tes événements utilisateurs, ce qui n'est pas jouable.
J'ai trouvé quelques articles sur ce sujet qui te donneront des infos intéressantes... à toi de voir comment tu veux implémenter tout ça :
- http://aspalliance.com/520_Detecting_ASPNET_Session_Timeouts.all
- http://www.codeproject.com/Articles/15575/Detecting-Session-Timeout-and-Redirect-to-HomePage
- http://www.eggheadcafe.com/tutorials/asp-net/7262426f-3c65-4c90-b49c-106470f1d22a/build-an-aspnet-session-timeout-redirect-control.aspx
- Proposé comme réponse Hervé DORIER jeudi 29 novembre 2012 16:54
- Marqué comme réponse Aurel Bera mardi 4 décembre 2012 08:26
-
Bonjour Yan et Hervé,
Merci pour toutes ces explications.
À propos de message d'erreur, faut-il préparer un gestionnaire dans laquelle il faut mettre mon erreur dans la liste?
Comment, je peux trouver la liste des gestionnaires actifs sur mon pc?
System.Exception' ne contient pas une définition pour 'ErrorCode' et aucune méthode d'extension 'ErrorCode' acceptant un premier argument de type 'System.Exception' n'a été trouvée (une directive using ou une référence d'assembly est-elle manquante ?)
En outre, pour le moment, j'ai personnalisé le message d'erreur avec mon web.config suite l'article suivant...
http://www.codeproject.com/Articles/2345/Custom-Errors-in-ASP-NET
Mais c'est pour tous les messages donc ce n'est pas bon... C'est bon pour le timeout, mais s'il y a d'autres erreurs... Par exemple le serveur mail ou serveur MySql tombe...
Du coup il ne faut pas afficher toujours le même message...C'est pour quoi, les mots clés try et catch est plus souple et plus adaptable selon l'erreur de l'utilisateur... Et surtout, si l'erreur ne vient pas de l'utilisateur...
Je suis en train de lire tous vos liens
Merci encore
Cordialement
-
L'option de la page d'erreur est très bonne aussi.
Je t'invite à lire cette page qui explique la gestion des exceptions dans les applications asp.net et comment mettre en place une page d'erreur dans laquelle tu vas pouvoir faire des traitements spécifiques en fonction de l'exception qui a été générée.
-
Bonjour,
Votre Exception provient d'un accès en base SQL donc il faut utiliser SqlException. A partir de cette classe d'exception, vous aurez le code d'exception. N'utilisez jamais une reconnaissance d'erreur par le message car si celui-ci est dans une autre langue, l'application ne traitera jamais votre code. Il faut impérativement utiliser ErrorCode.
La classe Exception est la haute hiérarchiquement et répond à une erreur tout genre (générique).
Est-ce que cela vous aides ?
Cordialement
Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !
- Marqué comme réponse Aurel Bera mardi 11 décembre 2012 08:28
-
Bonjour,
Est-ce que vous avez testé les solutions proposées ? Merci de partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.
Cordialement,
Aurel
-
Bonjour,
Pouvons-nous considérer que vous avez résolu votre problème avec les scénarios proposés ? Dans l'affirmative, pourriez-vous partager avec nous la solution, afin que d'autres personnes avec le même problème puissent profiter de cette solution ?
Désormais, nous marquons les solutions proposées. N'hésitez pas à revenir et supprimer la réponse marquée si la solution n’est pas correcte. Merci !
Cordialement,
Aurel
-