A exceção .NET capturada é inesperadamente nula
Veja abaixo uma explicação do que está acontecendo
Eu tenho um problema muito estranho, onde a exceção capturada é nul
O código usa o MEF e tenta arduamente relatar erros de composição. Usando o depurador, vejo a exceção sendo lançada (umInvalidOperationException
) mas quando é capturado pelo último bloco de captura no código abaixo doex
variável é nula. Isso é verdade tanto no depurador quanto ao executar o código normalment
static T ResolveWithErrorHandling<T>() where T : class
{
try
{
IocContainer.Compose(Settings.Default.IocConfiguration);
return IocContainer.Resolve<T>();
}
catch (ReflectionTypeLoadException ex)
{
// ... special error reporting for ReflectionTypeLoadException
}
catch (Exception ex)
{
// ex is null - that should not be possible!
// ... general error reporting for other exception types
}
return null;
}
O código que substitui pelos comentários é realmente um código simples para formatar a mensagem de erro. Nada de estranho está acontecendo lá.
Tentei alterar o código para descobrir que efeito isso pode ter:
Se eu remover o primeiro bloco de capturaReflectionTypeLoadException
) a exceção capturada no bloco de captura final não é mais nulSe eu pegar outro tipo de exceção no primeiro bloco de captura, a exceção capturada no bloco de captura final não será mais nul Se eu adicionar um bloco de captura paraInvalidOperationException
como o primeiro bloco de captura, a exceção capturada nesse bloco não é nul Se eu adicionar um bloco de captura paraInvalidOperationException
entre os dois blocos de captura, a exceção capturada nesse bloco é nulO projeto usaCode Contracts e o código gerado pelo compilador é pós-processado para verificar os contratos. Infelizmente, não descobri uma maneira de me livrar disso para fins de teste sem realizar uma grande cirurgia no projet
Minha solução atual é não pegarReflectionTypeLoadException
e, em vez disso, ramifique no tipo deex
no manipulador de exceção gera
Qual poderia ser a explicação para esse comportamento "impossível"? O que há comReflectionTypeLoadException
bloco de captura?
De maneira embaraçosa, a exceção não é nula e não pode ser nula de acordo com o padrão C # 15.9.
No entanto, usando contratos de código em um projeto pode atrapalhar a exibição de variáveis locais no depurador porque o código de IL gerado pelo compilador pode ser reescrito pelos Contratos de Código, para que o IL final fique ligeiramente fora de sincronia com as informações de depuração. No meu caso, oex
variável @ é exibida como nula, mesmo que não seja. A natureza infeliz do relatório de erros ocorrendo logo antes do encerramento do aplicativo significava que eu acreditava que o relatório de erros não seria chamado como resultado deex
sendo nulo eex.Message
jogando umNullReferenceException
dentro do meu bloco de captura. Usando o depurador, consegui "verificar" seex
era nulo, exceto que na verdade não era nul
Minha confusão foi agravada pelo fato de um bloco de captura paraReflectionTypeLoadException
parece afetar o problema de exibição do depurado
Obrigado a todos que responderam