Estava com um problema no tratamento de exceções do C#, pois em alguns pontos da aplicação a mensagem retornada dentro da propriedade Message da classe Exception não era a mensagem original gerada no ponto onde ocorreu a falha, isso me levou a efetuar pesquisas, e identifiquei o seguinte...
Uma prática muito utilizada é criarmos nossos try/catch e não tratarmos as exceções nas camadas de baixo nível da aplicação (como por exemplo a camada de banco de dados), desta forma somente forçamos o retorno da exceção para a camada de alto nível (por exemplo a camada de interface) para que ela faça o tratamento.Veja:
public void Teste()
{
try
{
throw new DivideByZeroException("Uma exceção de divisão por zero foi forçada.");
}
catch (DivideByZeroException ex)
{
throw (ex);
}
catch (Exception ex)
{
throw (ex);
}
}
Nos catch´s utilizamos o throw para reportar a exceção para a camada executora, assim na hora de tratarmos a exceção na camada de alto nível, não temos a certeza de qual o tipo de exceção que está sendo retornado, se IOException, se DivideByZeroException, se Exception, desta forma efetuamos o tratamento com a classe genérica que é a Exception para evitar falhas e interrupção da execução do aplicativo. Exemplo:
try
{
oObj.Teste();
}
catch (Exception ex)
{
global::System.Windows.Forms.MessageBox.Show(ex.Message);
}
O grande problema é que na ex.Message pode ocorrer de termos como retorno o seguinte conteúdo: "Exception has been thrown by the target of an invocation" e não o erro de divisão por zero forçado no código de exemplo anterior "Uma exceção de divisão por zero foi forçada.", deixando difícil a identificação da exceção para o usuário como para o programador.
Por não sabermos o tipo de exceção que será retornado e não termos que tratar todos os tipos de exceção existentes, pois são vários, podemos utilizar a seguinte solução:
try
{
oObj.Teste();
}
catch (Exception ex)
{
global::System.Windows.Forms.MessageBox.Show((ex.InnerException != null ? ex.InnerException.Message : ex.Message));
}
Sempre que não tivermos a certeza do tipo de exceção que será retornado, tratemos ela utilizando o conteúdo da InnerException, se for diferente de null, pegamos o conteúdo da propriedade Message dela, caso contrário continuamos com o Message da Exception.
Reforço que nem sempre a InnerException possui conteúdo, por isso que verificamos se ela é diferente de null, se for basta pegar o seu conteúdo que vamos ter o a informação original da exceção.