terça-feira, 10 de abril de 2007

Tratamento de erros: Objeto Exception parte 2

No post anterior sobre exceções, falei sobre o objeto Exception e como utilizá-lo para obter informações sobre erros ocorridos no sistema.


Agora falarei um pouco mais sobre esse objeto, explicando como pode ser utilizado para obter informações específicas a determinados tipos de erro e explicarei um pouco mais sobre a estrutura e funcionamento do bloco try..catch.

O object Exception é , na verdade, a classe base para os objetos que são gerados em caso de erro. Para cada tipo de erro, haverá um objeto diferente, herdando de exception. Esse objeto, dependendo do erro, pode disponibilizar informações adicionais sobre o erro. Se o programa efetuar uma divisão por zero, por exemplo, a exceção DivideByZeroException será gerada. Se for um erro ao executar um comando em um banco SQL Server, você obterá uma SQLException. Essas exceções herdam do objeto Exception, e por isso, possuem todas suas características. Alguns até adicionam informações extras. Quando você executa uma procedure no SQLServer, por exemplo, vários erros podem ocorrer durante a execução. Com o SQLException é possível acessar uma lista desses erros, incluindo informações como a severidade do erro.

Para tratar um erro, como mostrei no último post, você usa a seguinte estrutura :

try
{
// Código a ser tratado
}
catch(Exception ex)
{
// Código que irá tratar o erro.
}

Nesse exemplo, todo tipo de erro será capturado no mesmo bloco. Você pode, porém, criar blocos separados para cada tipo de erro, dessa forma:

try
{
// Código que pode gerar o erro
}
catch(SQLException ex)
{
// Código para tratar erros do SQL Server
}
catch(DivideByZeroException ex)
{
// Código para tratar erros de divisão por zero
}
catch(ArithmeticException ex)
{
// Código para tratar outros erros aritméticos.
}
catch(Exception ex)
{
// Código para tratar outros tipos de erro.
}
finally
{
// bloco que será executado dando ou não erro.
}

No bloco acima, trato vários tipos de erro. Quando um erro ocorre, ele é direcionado para o primeiro bloco catch que atenda a esse erro. É importante lembrar que um bloco Catch com uma determinada exceção, atende a esse exceção e a todas as exceções que herdarem dessas. Por isso, é importante que a ordem dos blocos a ser mantida seja do mais específico para o mais genérico. Se o Catch(Exception ex) estive no início , iria capturar todas as exceções (pois todas elas são exception, ou herdam de Exception), e nenhum dos outros blocos seria executado.

O bloco Finally será sempre executado, idependente de acontecer ou não um erro.

O Fluxo da execução ao acontecer um erro será:
  • Será executado apenas o primeiro bloco catch que atenda a exceção lançada, ou que atenda a umas das classes da hierarquia da qual a exceção herda.
  • O bloco finally será executado, caso haja um.
  • Se algum dos blocos catch atender à exceção, o erro será considerado tratado, e execução continuará do ponto após todo o bloco try..catch.
  • Se não houve um bloco catch que atendesse à exceção, a execução do método atual será interrompida, e o erro será lançado para o bloco try..catch acima, ou para o método que chamou. (Se houver um bloco finally, ele será chamado de qualquer forma).
Quando você escreve um bloco catch para tratar um erro, o erro será considerado tratado ali e após o bloco try..catch a execução continuará normalmente. Se você quiser tratar o erro, mas quiser que o erro ainda seja lançado para o método chamador, pode usar o comando throw, dentro do bloco try..catch.

try
{
// Comandos
}
catch (Exception Ex)
{
// Trata o erro
throw; // Repassa o erro
}

Porém, só faça isso se for fazer alguma coisa com o erro. Se for simplesmente repassar, como abaixo:

try
{
// Comandos
}
catch(Exception ex)
{
throw;
}

Isso não terá a menor funcionalidade, pois esse já é o comportamento padrão. E evite , acima de tudo :) , tratamentos que simplesmente ignorem o erro:

try
{
// Comandos
}
catch(Exception ex)
{}


Isso seria o equivalente a solucionar o problema daquele barulhinho estranho no seu carro com um tapa ouvidos. Você não perceberia mais o problema, mas ele estaria lá, e uma hora a coisa vai complicar.

Nenhum comentário: