Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Não entendi o por quê do preenchimento da stacktrace ser diferente com "throw" e "throw ex"

Olá,

Não ficou claro pra mim essa diferença. Pelo que entendo de exceções até o momento, ambos os jeitos "throw" e "throw ex" lançam o erro ao próximo método na pilha de chamadas. No meu entendimento, o método Sacar capturaria a exceção de ambas as formas e deveria tratá-las. Consequentemente, o rastro da pilha seria preenchido de maneira igual nos dois casos. Pq somente adicionando um nome de objeto "ex" já torna o preenchimento diferente? Essa é a minha dúvida.

3 respostas
solução!

Opa, Rodrigo. Tudo bom?

Quando lançamos uma exceção com a instrução throw <referência de exceção>; estamos avisando onde que esta exceção nasceu e é a partir do método em que esta instrução foi usada que a CLR preencherá o StackTrace.

Quando usamos apenas throw; estamos relançando a exceção criada dentro do bloco try - ou seja, a CLR vai manter o método de origem da exceção.

Exemplo:

1.) throw;

static void ChamaLancaExcecao()
{
    try
    {
        LancaExcecao();
    }
    catch (Exception e)
    {
        throw;
    }
}

Aqui a CLR mantém a exceção criada no bloco try. O método LancaExcecao continuará na StackTrace.

2.) throw <expressao de excecao>;

static void ChamaLancaExcecao()
{
    try
    {
        LancaExcecao();
    }
    catch (Exception e)
    {
        throw e;
    }
}

Aqui estamos dizendo onde a exceção nasceu e qual o ponto de partida da StackTrace. O método LancaExcecao não estará na pilha de chamadas!

Por coincidência, estamos lançando uma exceção que capturamos no bloco catch, mas, isto não importa. O que importa para a CLR é darmos uma referência de objeto de exceção e então a máquina virtual vai assumir que foi o método ChamaLancaExcecao que originou a exceção.

O que você acha? Ajudei com sua dúvida?

Abs.

Obrigado! Pode-se dizer que é raro o uso de throw ex?

o throw ex você pode usar sim para poder esconder informações sensíveis.

como o professor mostrou no exemplo de acesso ao saldo do cliente.

pode fazer uma exceção dentro de outra exceção com o InnerException e usar ex.

throw new Exception("Mensagem para esconder informaçoes originais da EX " ,  ex);