Visual Studio 2015 pause sur les exceptions non gérées ne fonctionne pas

114

Auparavant, Visual Studio avait une case à cocher spécifique pour "Annuler une exception non gérée". En 2015, cela a été supprimé (ou déplacé quelque part, je ne le trouve pas). Alors maintenant, mes projets convertis ne sont plus interrompus si je ne parviens pas à fournir un gestionnaire d'exceptions au niveau de l'utilisateur. Je ne veux pas interrompre toutes les "exceptions lancées" parce que je gère des exceptions spécifiques. Juste là où je ne parviens pas à fournir un gestionnaire spécifique.

À l'heure actuelle, mon code quitte simplement la procédure en cours et continue l'exécution à l'emplacement suivant de la pile d'appels, PAS BON.

Quelqu'un sait comment récupérer cela dans Visual Studio 2015? Je viens de passer à l'édition communautaire hier.

Ted Lowery
la source
Visual Studio 2015 conservera la disposition actuelle de votre version précédente, si ce n'est pas le cas, l' onglet Toolou Windowaura tous les emplacements souhaités. Dans votre cas, vous recherchez des paramètres d'exception .
Greg
4
@greg, ce n'est pas que je ne sais pas où trouver le panneau. Ma préoccupation est que le comportement que je recherche ne figure pas dans ce panel.
Ted Lowery
Même problème ici. Dans notre cas, nous nous attendons à une interruption d'exception lorsque l'autofac n'a pas tous les types enregistrés. En utilisant la même solution avec vs2013, cela fonctionne, dans vs2015, nous n'obtenons rien. c'est aussi un problème avec les autres enregistrements et exceptions tiers (comme nservicebus) .Je me demande si ce n'est le cas que pour le projet créé en vs2013 et exécuté en vs2015
Choco Smith
3
Cette nouvelle fenêtre d'outils est vraiment nul.
cedd
Selon les classifications MS des exceptions, si vous avez une exception non gérée, cela interrompt toujours le débogueur. Vous devrez peut-être cocher l'option "Pause lorsque les excptions traversent AppDomain ..." dans la liste "Options -> Débogage -> Général".
tsul

Réponses:

118

Une nouvelle fenêtre appelée "Paramètres d'exception" apparaît par défaut dans le volet inférieur droit lorsque vous commencez le débogage. Il a toutes les options que vous attendez.

Vous pouvez en parler avec CTRL+ ALT+E

Cela vous permet de sélectionner les exceptions qui provoquent une interruption du débogueur.

La clé, cependant, est que vous pouvez également définir si ces exceptions sont toujours interrompues ou ne sont interrompues que lorsqu'il s'agit d'une exception non gérée - mais la configuration n'est pas très intuitive.

Vous devrez d'abord cocher "Activer juste mon code" sous Outils> Options> Débogage.

Cela vous permet ensuite de cliquer avec le bouton droit de la souris sur l'en-tête de colonne (Break When Thrown) dans la nouvelle fenêtre Exceptions Settings, et d'ajouter la colonne "Additional Actions", qui vous permet ensuite de définir chaque exception comme "Continue when unhandled in user code".

Il vous suffit donc de cliquer avec le bouton droit de la souris sur une exception ou sur un groupe entier et de désactiver l'indicateur "Continuer si non géré dans le code utilisateur". Malheureusement, la colonne "Actions supplémentaires" apparaîtra vide, ce qui équivaut à "Pause si non gérée dans le code utilisateur".

entrez la description de l'image ici

Plus à ce sujet ici:

http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx

Tom Studee
la source
7
En fait, cette fenêtre n'a que des options pour "rompre avec jeté". Ce n'est pas ce que je veux. Je veux "casser quand non géré".
Ted Lowery
17
Et voilà le problème. Il ne casse PAS. comme je l'ai dit ci-dessus, il sort (sort) de l'appel de procédure en cours et commence simplement à exécuter la ligne de code suivante dans la procédure d'appel.
Ted Lowery
2
et j'ai activé "Juste mon code".
Ted Lowery
19
@TomStudee J'ai aussi le même problème. Ce que je veux, c'est "Break when nonhandled" mais ce que j'obtiens c'est "Break when thrown". La question est: comment obtenir "Pause quand non gérée"?
ogggre
1
@TomStudee Je viens d'ajouter quelques précisions indispensables, car il vous manquait le paramètre clé qui vous permet de définir des exceptions à ne rompre que lorsqu'elles ne sont pas gérées.
Jerad Rose
36

J'ai eu le même problème et j'ai réussi à le résoudre en faisant ceci -

  1. Appuyez sur Ctrl+ Alt+ epour afficher la fenêtre Paramètres d'exception .
  2. Cochez les exceptions Common Language Runtime . entrez la description de l'image ici

C'est tout!

J'ai été inspiré par cet article car j'utilise une version x64 de Windows .

Justin XL
la source
7
Cela entraînera sa rupture sur toutes les exceptions, même celles gérées par le code utilisateur.
carlin.scott
1
@ carlin.scott, je pense que vous pouvez décocher manuellement les exceptions gérées dans la liste.
Justin XL
6
@JustinXL Le problème est qu'il s'agit d'une liste par type d'exception, et non selon qu'elle est gérée ou non. Par exemple, il y a des moments où System.ArgumentExceptionest géré et des moments où ce n'est pas le cas. Je me soucie seulement de casser quand ce n'est pas manipulé.
Jerad Rose
1
@JeradRose Le débogueur s'arrêtera toujours lorsqu'une exception n'est pas gérée. Donc, comme je l'ai dit, si vous ne voulez pas de pause sur les exceptions gérées, décochez simplement ces types d'exception dans la liste Break When Thrown .
Justin XL
Même en vérifiant tout, cela ne casse pas sur une exception: / juste en sortant
Douglas Gaskell
10

Pour les googleurs qui souhaitent se casser uniquement lorsque l'exception concerne leur code, il existe une option dans Visual Studio 2015: Options-> Débogage-> Général-> Juste mon code. Une fois coché, il permet de ne pas casser lorsque l'exception est gérée (levée et interceptée) en dehors de votre code.

Olivier de Rivoyre
la source
Cela m'a sauvé pour une autre situation où VS2015, pour une raison quelconque, a refusé d'entrer du code. Le code est "à moi" mais quelque chose a déclenché le drapeau "Juste mon code". Je suppose qu'il y a un bogue quelque part lors de l'exécution de 2 instances de VS et d'un serveur Web autonome et probablement d'autres.
LosManos
9

Microsoft a subtilement modifié la logique dans la nouvelle fenêtre d'exceptions.

Voir http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx

L'élément clé étant:

Notes IMPORTANTES

  • Cette nouvelle fenêtre contient toutes les mêmes fonctionnalités que l'ancienne boîte de dialogue modale. Aucune fonctionnalité du débogueur n'a changé uniquement la façon dont vous pouvez y accéder
  • Le débogueur s'arrêtera toujours lorsqu'une exception n'est pas gérée
  • Le paramètre à modifier si le débogueur s'arrête sur les exceptions non gérées par l'utilisateur a été déplacé sous un menu contextuel
  • L'emplacement du menu a été déplacé vers Débogage -> Windows -> Paramètres d'exception

Cependant , si comme moi vous avez un Global Unhandled Exception Handler dans votre code, le deuxième élément de cette liste est essentiel: pour moi, aucune exception ne sera donc vraiment non gérée, ce qui semble être différent de VS2013.

Pour rétablir le comportement où VS se casse sur les exceptions non gérées, j'ai dû cocher tous les types d'exceptions sur lesquels je voulais interrompre puis m'assurer que les "Options supplémentaires" (vous devrez peut-être rendre cette colonne visible *) pour "Continuer lorsqu'il n'est pas géré dans le code utilisateur "n'était PAS défini. La logique VS2015 ne semble pas considérer mon gestionnaire d'exceptions global non géré comme étant "géré dans le code utilisateur", donc il se casse sur ceux-ci; il ne casse pas sur les exceptions capturées cependant. Cela le fait fonctionner comme VS2013 l'a fait.

* Comment activer la colonne "Actions supplémentaires" * Comment activer la colonne "Actions supplémentaires"

avoine
la source
2
Cela ne fonctionne pas exactement comme VS2013 car il se cassera sur les exceptions gérées par l'utilisateur avec les paramètres que vous avez suggérés, ce qui n'était pas le cas dans le passé.
carlin.scott
Comment rendre visible la colonne "Options supplémentaires"?
UuDdLrLrSs
@DaveInCaz Faites un clic droit sur l'en-tête de la colonne> "Afficher les colonnes"> "Actions supplémentaires"
oatsoda
7

Si je lis correctement entre les lignes ici, le problème est que votre exception «disparaît» effectivement, même si le comportement du débogueur par défaut doit être interrompu sur les exceptions non gérées.

Si vous disposez de méthodes asynchrones, vous rencontrez peut-être ce problème car les exceptions non interceptées sur un thread de pool de threads dans le cadre d'une continuation de tâche ne sont pas considérées comme des exceptions non gérées. Au contraire, ils sont avalés et stockés avec la tâche.

Par exemple, jetez un œil à ce code:

class Program
{
    static void Main(string[] args)
    {
        Test();
        Console.ReadLine();
    }

    private async static Task Test()
    {
        await Task.Delay(100);
        throw new Exception("Exception!");
    }
}

Si vous exécutez ce programme avec les paramètres du débogueur par défaut (arrêt uniquement sur les exceptions non gérées), le débogueur ne s'arrêtera pas. Cela est dû au fait que le thread du pool de threads alloué à la suite avale l'exception (en la transmettant à l'instance Task) et se libère dans le pool.

Notez que, dans ce cas, le vrai problème est que le Taskrenvoyé par Test()n'est jamais vérifié. Si vous avez des types similaires de logique «feu et oubliez» dans votre code, vous ne verrez pas les exceptions au moment où elles sont lancées (même si elles ne sont pas gérées dans la méthode); l'exception n'apparaît que lorsque vous observez la tâche en l'attendant, en vérifiant son résultat ou en regardant explicitement son exception.

Ce n'est qu'une supposition, mais je pense que vous observez probablement quelque chose comme ça.

Dan Bryant
la source
Bien que cela puisse ne pas être lié au problème de l'opération, cela soulève un très bon point sur les exceptions soulevées dans les routines asynchrones.
Phil Cooper
Existe-t-il un moyen d'arrêter le débogueur même si l'exception est stockée comme ça?
Lucas
@Lucas, pas que je sache, bien que vous puissiez vous rapprocher de quelques changements de code. Si le corps de votre méthode fire-and-forget a un bloc try-catch, vous pouvez ajouter un Debugger.Break()appel explicite . Alternativement, vous pouvez ajouter un explicite Debugger.Break()dans le TaskScheduler.UnobservedTaskExceptiongestionnaire, bien que l'inconvénient ici soit que cela peut se déclencher beaucoup plus tard que l'exception d'origine, comme cela se produit sur le thread du finaliseur lorsque la tâche est nettoyée. En général, vous devez vous efforcer de toujours observer les résultats de la tâche ou au moins avoir un bloc try-catch à enregistrer au moment de l'échec.
Dan Bryant
3

D'après mon expérience, les paramètres d'exception en 2015 sont complètement déstabilisés si vous changez quoi que ce soit.

On s'attend à ce que si vous atteignez le groupe parent "CLR", vous ne devriez pas obtenir d'execpt de rupture pour non géré. Vous serez toujours interrompu si une exception n'est pas gérée. Mais, si vous avez décoché le groupe CLR, le code à l'intérieur d'un try ... catch ne devrait tout simplement pas provoquer de coupure. Ce n'est pas le cas.

Solution: dans la nouvelle boîte à outils des paramètres d'exception, cliquez avec le bouton droit de la souris et choisissez «restaurer les paramètres par défaut». Taadaaaa ... Il se comporte à nouveau normalement. Maintenant, ne foutez pas ça.

Clint StLaurent
la source
1

Essayez de suivre les instructions:

  1. Dans la fenêtre Paramètres d'exception, ouvrez le menu contextuel en cliquant avec le bouton droit de la souris dans la fenêtre, puis en sélectionnant Afficher les colonnes. (Si vous avez désactivé Just My Code, vous ne verrez pas cette commande.)
  2. Vous devriez voir une deuxième colonne intitulée Actions supplémentaires. Cette colonne affiche Continuer lorsqu'elle n'est pas gérée par le code utilisateur sur des exceptions spécifiques, ce qui signifie que le débogueur ne rompt pas si cette exception n'est pas gérée dans le code utilisateur mais est gérée dans le code externe.
  3. Vous pouvez modifier ce paramètre pour une exception particulière (sélectionnez l'exception, cliquez avec le bouton droit de la souris et sélectionnez / désélectionnez Continuer si non gérée dans le code utilisateur) ou pour une catégorie entière d'exceptions (par exemple, toutes les exceptions Common Language Runtime).

https://msdn.microsoft.com/en-us/library/x85tt0dd.aspx

Andrei
la source
Tout à fait d'accord. C'est horrible de ne pas afficher cette colonne par défaut. J'ai passé beaucoup de temps à le trouver. En outre, ce que signifie « exception non gérée par l' utilisateur » n'est pas clair. J'avais mon gestionnaire d'une annulation de tâche (quelque chose comme try { task.Wait(); } catch { ... }) et OperationCanceledException dans la tâche était considérée comme non gérée dans le code utilisateur d'une manière ou d'une autre.
tsul
1

Tout cela est un peu déroutant, et à mon avis pas aussi bon que l'ancien dialogue des exceptions, mais de toute façon.

Si une exception est dans la liste et cochée, le débogueur s'arrêtera chaque fois que l'exception est levée.

Si une exception est décochée ou non dans la liste, le débogueur ne sera interrompu que lorsque ce type d'exception n'est pas géré par l'utilisateur.

Par exemple, dans la capture d'écran ci-dessous, le débogueur s'arrêtera chaque fois que a System.AccessViolationExceptionest lancé, mais pour toutes les autres exceptions, il ne sera interrompu que si l'exception n'a pas été gérée par l'utilisateur.

Fenêtre de l'outil d'exceptions de Visual Studio 2015

cedd
la source
1

Lors de la mise à niveau vers VS2015, j'ai également eu des problèmes où les exceptions "cassaient" l'application, mais sont maintenant ignorées et passées directement. Il y a des moments où nous voulons que notre code lève intentionnellement des exceptions là où nous voulons que le code s'arrête, plutôt que de continuer. Nous utilisons toujours la phrase Throw New Exception("Message")pour que notre code se brise intentionnellement:

    If SomethingReallyBad = True Then
        Throw New Exception("Something Really Bad happened and we cannot continue.")
    End If

Avec VS2015, c'est le classique "System.Exception" qui est lancé quand on dit Throw New Exception. Par conséquent, nous devions cocher la case "System.Exception" dans les nouveaux paramètres d'exception:

Vérifiez la boîte System.Exception

Une fois vérifié, notre code a fonctionné comme prévu.

J.Wyckoff
la source
1

La solution est que cela est sémantiquement le contraire de ce que vous pensez définir. Vous devez vous assurer que Continuer lorsque non géré dans le code utilisateur n'est pas activé, c'est- à- dire qu'il n'est pas coché comme indiqué dans la colonne Actions supplémentaires de l' onglet Paramètres d'exception - voir ci-dessous:

vous dites effectivement ne pas continuer (c'est-à-dire interrompre) lorsqu'il n'est pas géré dans le code

Fenêtre Paramètres d'exception (Ctrl + Alt + E)

Pour faire ça:

  1. Cliquez avec le bouton droit de la souris sur l'exception ou l'ensemble d'exceptions qui vous tient à cœur (c'est-à-dire généralement la ligne supérieure 'Common Language Runtime Exceptions' dans l'arborescence)
  2. Sélectionnez l'option Continuer si non géré dans le code d'utilisateur (voir ci-dessous)
  3. Assurez-vous que les exceptions ne sont pas vérifiées (voir ci-dessous)
  4. continuer le débogage

entrez la description de l'image ici

Cela l'a fait pour moi - heureux à nouveau.

C'était dans VS 2015

Simon Sanderson
la source
0

Il y a certainement un bogue dans Visual Studio qui peut le bloquer et nécessiter un redémarrage. Même VS2015.

J'ai eu une situation à un seul thread où a NullReferenceExceptionétait intercepté par un gestionnaire «externe» (toujours dans mon code) même si je lui ai demandé de se casser quand il a été déclenché.

Je me rends compte que c'est une exception «gérée» et que vous parlez d'une exception «non gérée» - mais je suis presque sûr que parfois un redémarrage rapide de VS résoudra ce problème, si IISRESET ne le fait pas.

Simon_Weaver
la source
0

Visual Studio 2017 fonctionne très bien avec la gestion des erreurs. Visual Studio 2015, d'autre part, aspire à la gestion des erreurs avec les tâches car en mode débogage, toutes les exceptions qui se produisent dans une tâche asynchrone sont interceptées, mais si je marche dessus, cela se bloque indéfiniment. S'il est exécuté sans débogage, il se bloque indéfiniment sans aucune exception interceptée !!! J'adore Visual Studio et je l'utilise depuis 1995 et 2015 est de loin la pire version bien que j'aie sauté de 2010 directement à 2015. J'ai passé 8 heures à essayer de faire fonctionner cette gestion des exceptions sans succès. J'ai copié le code exact de 2017 sur mon ordinateur personnel et cela a parfaitement fonctionné. Je suis très irrité que Microsoft ait poussé des tâches dans un cadre que le compilateur 2015 ne peut pas gérer correctement.

Moïse
la source