Comment attraper toutes les exceptions / pannes dans une application .NET

Duplication possible:
.NET – Quelle est la meilleure façon d’implémenter un “gestionnaire d’exceptions catch all”

J’ai une application d’application de console .NET qui plante et affiche un message à l’utilisateur. Tout mon code est dans un bloc try{} catch(Exception e){} , mais des erreurs sont parfois affichées.

Dans une application Win32, vous pouvez capturer toutes les exceptions / pannes possibles en installant différents gestionnaires d'exceptions:

 /* C++ exc handlers */ _set_se_translator SetUnhandledExceptionFilter _set_purecall_handler set_terminate set_unexpected _set_invalid_parameter_handler 

Qu'est-ce que l'équivalent dans le monde .NET pour que je puisse gérer / enregistrer / désactiver tous les cas d'erreur possibles?

Contrairement à ce que d’autres ont publié, il n’y a rien de mal à saisir toutes les exceptions. L’important est de les traiter de manière appropriée. Si vous avez une condition de dépassement de capacité de la stack ou de mémoire insuffisante, l’application devrait s’arrêter pour eux. De plus, gardez à l’esprit que les conditions de MOO peuvent empêcher votre gestionnaire d’exceptions de s’exécuter correctement. Par exemple, si votre gestionnaire d’exceptions affiche une boîte de dialog avec le message d’exception, si vous manquez de mémoire, il peut ne pas y en avoir assez pour l’affichage de la boîte de dialog. Mieux vaut le connecter et le fermer immédiatement.

Comme d’autres l’ont mentionné, il existe les événements UnhandledException et ThreadException que vous pouvez gérer pour les exceptions de collecte qui pourraient sinon être manquées. Ensuite, lancez simplement un gestionnaire d’exceptions autour de votre boucle principale (en supposant une application winforms).

De plus, vous devez savoir que les exceptions OutOfMemoryExceptions ne sont pas toujours renvoyées pour des conditions de mémoire insuffisante. Une condition de MOO peut déclencher toutes sortes d’exceptions, dans votre code ou dans la structure, qui n’ont rien à voir avec le fait que la condition sous-jacente réelle est insuffisante. J’ai souvent vu InvalidOperationException ou ArgumentException lorsque la cause sous-jacente est en réalité hors de la mémoire.

Vous pouvez append un gestionnaire d’événement à l’événement AppDomain.UnhandledException, qui sera appelé lorsqu’une exception sera levée et non interceptée.

Cet article dans Codeproject de notre hôte Jeff Atwood est ce dont vous avez besoin. Inclut le code pour intercepter les exceptions non gérées et les meilleures pratiques pour afficher des informations sur la panne à l’utilisateur.

La classe Global.asax est votre dernière ligne de défense. Regarder:

 protected void Application_Error(Object sender, EventArgs e) 

méthode

Sachez que certaines exceptions sont dangereuses à attraper – ou presque impossibles à détecter,

  • OutOfMemoryException: tout ce que vous faites dans le gestionnaire de capture peut allouer de la mémoire (du côté géré ou non géré du CLR) et déclencher ainsi un autre MOO
  • StackOverflowException: selon que le CLR l’a détecté suffisamment tôt, vous pourriez être averti. Dans le pire des cas, cela tue simplement le processus.

Vous pouvez utiliser l’exception AppDomain.CurrentDomain.UnhandledException pour obtenir un événement.

Bien que trouver toutes les exceptions sans prévoir de les gérer correctement soit une mauvaise pratique, je pense qu’une application devrait échouer de manière gracieuse. Un crash ne devrait pas effrayer l’utilisateur, et au moins il devrait afficher une description de l’erreur, des informations à rapporter au support technique et, idéalement, un bouton pour fermer l’application et le redémarrer. Dans un monde idéal, l’application devrait être capable de transférer sur le disque les données de l’utilisateur, puis d’essayer de les récupérer (mais je constate que c’est trop demander).

En tout cas, j’utilise habituellement:

 AppDomain.CurrentDomain.UnhandledException 

Vous pouvez également aller avec Application.ThreadException Event.

Une fois que je développais une application .NET s’exécutant dans une application basée sur COM; Cet événement était très utile, car AppDomain.CurrentDomain.UnhandledException ne fonctionnait pas dans ce cas.

Je pense que vous ne devriez même pas attraper toutes les exceptions, mais mieux les laisser montrer à l’utilisateur. La raison en est que vous ne devez intercepter que les exceptions que vous pouvez réellement gérer. Si vous rencontrez des exceptions qui provoquent l’arrêt du programme tout en le détectant, cela peut entraîner des problèmes beaucoup plus graves. Lisez également la FAQ: Pourquoi FxCop met-il en garde contre la capture (Exception)? .

Sachez que la capture de ces exceptions non gérées peut modifier les exigences de sécurité de votre application. Votre application peut cesser de fonctionner correctement dans certains contextes (lorsqu’elle est exécutée à partir d’un partage réseau, etc.). Assurez-vous de bien tester.

l’utilisation de AppDomain.CurrentDomain.UnhandledException Application.ThreadException ne fait pas mal

mais gardez à l’esprit que les exceptions sur les threads secondaires ne sont pas interceptées par ces gestionnaires; utilisez SafeThread pour les threads secondaires si nécessaire