Por que o TargetInvocationException é tratado como não capturado pelo IDE?
-
27-09-2019 - |
Pergunta
Eu tenho algum código que está usando a reflexão para extrair valores de propriedade de um objeto. Em alguns casos, as propriedades podem lançar exceções, porque têm referências nulas, etc.
object result;
try
{
result = propertyInfo.GetValue(target, null);
}
catch (TargetInvocationException ex)
{
result = ex.InnerException.Message;
}
catch (Exception ex)
{
result = ex.Message;
}
Por fim, o código funciona corretamente, no entanto, quando estou correndo sob o depurador:
Quando a propriedade lança uma exceção, o IDE cai no depurador como se a exceção fosse desativada. Se eu acabou de chegar ao Run, o programa flui e a exceção será lançada como um TargetInvocationException, com a exceção real na propriedade InNerexception.
Como posso impedir que isso aconteça?
Solução
Isso parece ser "por design". O que acontece é que você provavelmente tem menu Ferramentas → Opções → Depuração → Em geral → Habilite apenas meu código ativado.
Como Como: quebrar as exceções não usadas pelo usuário estados:
o Depurar → Exceções A caixa de diálogo mostra uma coluna adicional (quebra quando uma exceção é usada) quando "Ativar apenas meu código" está ativado.
Essencialmente, isso significa que sempre que a exceção está deixando o limite do seu código (e, nesse caso, ele cai no código de reflexão da estrutura .NET), quebra o Visual Studio porque acha que a exceção deixou o código do usuário. Não sabe que ele retornará ao código do usuário posteriormente na pilha.
Portanto, existem duas soluções alternativas: desativar Apenas meu código no menu Ferramentas → Opções → Depuração → Em geral ou Remova a caixa de seleção das exceções da estrutura .NET de manipulamento de usuário no menu Depurar → Exceções diálogo.
Outras dicas
EDIT: Acabei de experimentar isso sozinho, e parece que a reflexão é tratada de maneira um pouco diferente. Você pode querer pensar em uma chamada de reflexão como iniciando um novo nível de "manipulado" no que diz respeito ao depurador: nada está pegando essa exceção antes de ser traduzido e renegado como um TargetInvocationException
, então ele se divide. Não sei se há alguma maneira de inibir isso - mas isso acontece com muita frequência? Se você estiver executando regularmente muitas operações que resultam em exceções, convém reconsiderar seu design.
Resposta original
Vá para depuração / exceções ... e veja quais são as configurações. Você verá esse comportamento se TargetInvocationException
(ou qualquer coisa mais alta na hierarquia) tem a caixa de ticks "jogada" verificada.